├── VERSION ├── system-load-generator ├── configs ├── const_cpuload_config.yaml ├── cpuload_config.yaml ├── loadaverage_config.yaml └── cpuload_memorypressure_config.yaml ├── .gitignore ├── Dockerfile ├── LICENSE ├── settings.gradle ├── src └── main │ └── java │ └── loadgenerator │ ├── strategies │ ├── LoadGenerationStrategyI.java │ ├── factory │ │ ├── SimpleStrategyFactoryI.java │ │ ├── UnsupportedLoadTypeException.java │ │ └── SimpleStrategyFactory.java │ ├── ConstantCPULoad.java │ ├── ConstIncreaseCPULoad.java │ ├── ConstIncreaseLoadAverage.java │ └── CPULoadGeneratorWithMemoryPressure.java │ ├── driver │ ├── UsageException.java │ ├── CLIBuilder.java │ └── Driver.java │ ├── entities │ └── ProcessorArchInfo.java │ └── util │ ├── ProcessorArch.java │ ├── LoadAverage.java │ └── CPULoad.java └── README.md /VERSION: -------------------------------------------------------------------------------- 1 | 2.1-SNAPSHOT 2 | -------------------------------------------------------------------------------- /system-load-generator: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | gradle run --args="'$@'" -------------------------------------------------------------------------------- /configs/const_cpuload_config.yaml: -------------------------------------------------------------------------------- 1 | cpuLoad: 0.6 2 | duration: 70000 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.class 2 | *.swp 3 | .vscode/ 4 | .gradle/ 5 | .idea/ 6 | **/build/ 7 | -------------------------------------------------------------------------------- /configs/cpuload_config.yaml: -------------------------------------------------------------------------------- 1 | stepSize: 0.2 2 | duration: 3000 3 | isAlt: false 4 | segments: 2 5 | -------------------------------------------------------------------------------- /configs/loadaverage_config.yaml: -------------------------------------------------------------------------------- 1 | startLoadAverage: 0.25 # assuming quad-core machine. 2 | stepSize: 0.2 -------------------------------------------------------------------------------- /configs/cpuload_memorypressure_config.yaml: -------------------------------------------------------------------------------- 1 | minCpuLoadPercentage: 0.2 2 | maxCpuLoadPercentage: 0.6 3 | ramUsageBytes: 2048 -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | # Generate CPU load for the given number of threads and cores. 2 | # Generate Load Average. 3 | # Load.java forked from https://gist.github.com/SriramKeerthi/0f1513a62b3b09fecaeb 4 | # Generate CPU Load with Memory Pressure. 5 | 6 | FROM openjdk:8 7 | 8 | # Gradle Installation. 9 | # Cite: https://gordonlesti.com/building-a-gradle-docker-image 10 | # Installing v6.3 as higher versions don't seem to work. 11 | RUN wget -q https://services.gradle.org/distributions/gradle-6.3-bin.zip \ 12 | && unzip gradle-6.3-bin.zip -d /opt \ 13 | && rm gradle-6.3-bin.zip 14 | 15 | ENV GRADLE_HOME /opt/gradle-6.3 16 | ENV PATH $PATH:/opt/gradle-6.3/bin 17 | 18 | # Copying the source files into the Docker container's root directory. 19 | COPY . / 20 | 21 | # Compile. 22 | RUN gradle clean && gradle build 23 | 24 | # Default = help string. 25 | CMD ["-h"] 26 | 27 | ENTRYPOINT ["./system-load-generator"] 28 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 PRADYUMNA KAUSHIK 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 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | /** 2 | * MIT License 3 | * 4 | * Copyright (c) 2019 PRADYUMNA KAUSHIK 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | rootProject.name = 'system-load-generator' -------------------------------------------------------------------------------- /src/main/java/loadgenerator/strategies/LoadGenerationStrategyI.java: -------------------------------------------------------------------------------- 1 | /** 2 | * MIT License 3 | *
4 | * Copyright (c) 2019 PRADYUMNA KAUSHIK 5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | *
13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | package loadgenerator.strategies; 25 | 26 | public interface LoadGenerationStrategyI { 27 | void execute(); 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/loadgenerator/strategies/factory/SimpleStrategyFactoryI.java: -------------------------------------------------------------------------------- 1 | /** 2 | * MIT License 3 | *
4 | * Copyright (c) 2019 PRADYUMNA KAUSHIK 5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | *
13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | package loadgenerator.strategies.factory; 25 | 26 | import java.io.IOException; 27 | 28 | import loadgenerator.strategies.LoadGenerationStrategyI; 29 | 30 | public interface SimpleStrategyFactoryI { 31 | LoadGenerationStrategyI getLoadGenerationStrategy(String loadType) 32 | throws UnsupportedLoadTypeException, IOException; 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/loadgenerator/strategies/factory/UnsupportedLoadTypeException.java: -------------------------------------------------------------------------------- 1 | /** 2 | * MIT License 3 | *
4 | * Copyright (c) 2019 PRADYUMNA KAUSHIK 5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | *
13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | package loadgenerator.strategies.factory; 25 | 26 | public class UnsupportedLoadTypeException extends IllegalArgumentException { 27 | public UnsupportedLoadTypeException(String message) { 28 | super(message); 29 | } 30 | 31 | public UnsupportedLoadTypeException(String message, Throwable throwable) { 32 | super(message, throwable); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/loadgenerator/driver/UsageException.java: -------------------------------------------------------------------------------- 1 | /** 2 | * MIT License 3 | *
4 | * Copyright (c) 2019 PRADYUMNA KAUSHIK 5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | *
13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | package loadgenerator.driver; 25 | 26 | public final class UsageException extends RuntimeException { 27 | private final String message; 28 | 29 | public UsageException(final String message) { 30 | this.message = message; 31 | } 32 | 33 | public UsageException() { 34 | this.message = "Usage Error!" + "\n" + CLIBuilder.getOptions(); 35 | } 36 | 37 | @Override 38 | public String getMessage() { 39 | return message; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/loadgenerator/driver/CLIBuilder.java: -------------------------------------------------------------------------------- 1 | /** 2 | * MIT License 3 | *
4 | * Copyright (c) 2019 PRADYUMNA KAUSHIK 5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | *
13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | package loadgenerator.driver; 25 | 26 | import org.apache.commons.cli.Options; 27 | 28 | public final class CLIBuilder { 29 | private static final Options OPTIONS = new Options(); 30 | 31 | static { 32 | // Defining command line options. 33 | OPTIONS.addOption("lT", "load-type", true, "Type of load to be generated"); 34 | OPTIONS.addOption("h", "help", false, "Usage information"); 35 | } 36 | 37 | private CLIBuilder() { 38 | } 39 | 40 | /** 41 | * Retrieve the command line options. 42 | * @return command line options. 43 | */ 44 | public static Options getOptions() { 45 | return OPTIONS; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/loadgenerator/entities/ProcessorArchInfo.java: -------------------------------------------------------------------------------- 1 | /** 2 | * MIT License 3 | *
4 | * Copyright (c) 2019 PRADYUMNA KAUSHIK 5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | *
13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | package loadgenerator.entities; 25 | 26 | public class ProcessorArchInfo { 27 | private final int numCores; 28 | private final int numThreadsPerCore; 29 | 30 | public ProcessorArchInfo(int numCores, int numThreadsPerCore) { 31 | this.numCores = numCores; 32 | this.numThreadsPerCore = numThreadsPerCore; 33 | } 34 | 35 | public int getNumCores() { 36 | return this.numCores; 37 | } 38 | 39 | public int getNumThreadsPerCore() { 40 | return this.numThreadsPerCore; 41 | } 42 | 43 | public String toString() { 44 | return "Processor Architecture Information\n--------------------------------\n" + "Total number of cores (num of cores per socket * num of sockets) = " + 45 | this.numCores + 46 | "\n" + 47 | "Number of threads per core = " + 48 | this.numThreadsPerCore + 49 | "\n"; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/loadgenerator/util/ProcessorArch.java: -------------------------------------------------------------------------------- 1 | /** 2 | * MIT License 3 | *
4 | * Copyright (c) 2019 PRADYUMNA KAUSHIK 5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | *
13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | package loadgenerator.util; 25 | 26 | import loadgenerator.entities.ProcessorArchInfo; 27 | 28 | import java.io.BufferedReader; 29 | import java.io.InputStreamReader; 30 | 31 | public class ProcessorArch { 32 | 33 | /** 34 | * Determine the following information about the underlying processor architecture, 35 | * 1. Number of cores 36 | * 2. Number of threads per core 37 | */ 38 | public static ProcessorArchInfo getProcessorArchInformation() throws Exception { 39 | Process p = Runtime.getRuntime().exec("lscpu"); 40 | BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream())); 41 | String line = ""; 42 | int numCores = 0; 43 | int numThreadsPerCore = 0; 44 | int numSockets = 0; 45 | int numCoresPerSocket = 0; 46 | while ((line = br.readLine()) != null) { 47 | if (line.contains("Socket(s):")) { 48 | // Retrieving the number of sockets 49 | String[] lineComponents = line.split("\\s+"); 50 | numSockets = Integer.parseInt(lineComponents[lineComponents.length - 1]); 51 | } else if (line.contains("Core(s) per socket:")) { 52 | // Retrieving the number of cores per socket. 53 | // Total number of cores would be NumCoresPerSocket * NumSockets 54 | String[] lineComponents = line.split("\\s+"); 55 | numCoresPerSocket = Integer.parseInt(lineComponents[lineComponents.length - 1]); 56 | } else if (line.contains("Thread(s) per core:")) { 57 | // Retrieving the number of threads per core. 58 | String[] lineComponents = line.split("\\s+"); 59 | numThreadsPerCore = Integer.parseInt(lineComponents[lineComponents.length - 1]); 60 | } 61 | } 62 | // Determining the total number of cores. 63 | numCores = numCoresPerSocket * numSockets; 64 | return new ProcessorArchInfo(numCores, numThreadsPerCore); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/main/java/loadgenerator/util/LoadAverage.java: -------------------------------------------------------------------------------- 1 | /** 2 | * MIT License 3 | *
4 | * Copyright (c) 2019 PRADYUMNA KAUSHIK 5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | *
13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | package loadgenerator.util;
25 |
26 | import java.util.Random;
27 | import java.util.concurrent.ExecutorService;
28 | import java.util.concurrent.Callable;
29 | import java.util.concurrent.Future;
30 | import java.util.concurrent.Executors;
31 | import java.util.List;
32 | import java.util.ArrayList;
33 | import java.util.concurrent.ExecutionException;
34 |
35 | public class LoadAverage {
36 |
37 | /**
38 | * Creates load for the given amount of time.
39 | * @param numThreadsToCreate Number of threads to create so as to generate the required 1min load average.
40 | * @param duration Amount of time to maintain the load.
41 | */
42 | public static void createLoad(int numThreadsToCreate, long duration) throws InterruptedException, ExecutionException {
43 |
44 | // Defining what each thread is going to execute.
45 | Callable
4 | * Copyright (c) 2019 PRADYUMNA KAUSHIK
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | package loadgenerator.driver;
25 |
26 | import java.io.IOException;
27 |
28 | import org.apache.commons.cli.CommandLine;
29 | import org.apache.commons.cli.CommandLineParser;
30 | import org.apache.commons.cli.DefaultParser;
31 | import org.apache.commons.cli.HelpFormatter;
32 | import org.apache.commons.cli.ParseException;
33 |
34 | import loadgenerator.strategies.factory.SimpleStrategyFactoryI;
35 | import loadgenerator.strategies.factory.SimpleStrategyFactory;
36 | import loadgenerator.strategies.factory.UnsupportedLoadTypeException;
37 | import loadgenerator.strategies.LoadGenerationStrategyI;
38 |
39 | public class Driver {
40 | public static void main(final String[] args) {
41 | CommandLineParser commandLineParser = new DefaultParser();
42 | CommandLine commandLine;
43 | // Parsing command line arguments.
44 | if (0 == args.length) {
45 | throw new UsageException();
46 | } else {
47 | try {
48 | commandLine = commandLineParser.parse(CLIBuilder.getOptions(), args);
49 | } catch (ParseException e) {
50 | e.printStackTrace();
51 | throw new UsageException(e.getMessage());
52 | }
53 | }
54 | // Printing possible command line options and exiting.
55 | if (commandLine.hasOption("help")) {
56 | HelpFormatter helpFormatter = new HelpFormatter();
57 | helpFormatter.printHelp("java -jar build/libs/system-load-generator-
4 | * Copyright (c) 2019 PRADYUMNA KAUSHIK
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | package loadgenerator.strategies;
25 |
26 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
27 | import com.fasterxml.jackson.databind.ObjectMapper;
28 | import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
29 | import loadgenerator.entities.ProcessorArchInfo;
30 | import loadgenerator.util.CPULoad;
31 | import loadgenerator.util.ProcessorArch;
32 |
33 | import java.io.File;
34 | import java.io.IOException;
35 |
36 | public class ConstantCPULoad implements LoadGenerationStrategyI {
37 | // Setting default cpu load to be 50%.
38 | private static final double DEFAULT_CPU_LOAD = 0.5;
39 | // Setting default duration for the load to be 60sec.
40 | private static final int DEFAULT_DURATION = 60000;
41 | private static ProcessorArchInfo processorArchInfo = null;
42 |
43 | // Non-defaults.
44 | private double cpuLoad = DEFAULT_CPU_LOAD;
45 | private int duration = DEFAULT_DURATION;
46 |
47 | static {
48 | // Retrieving the processor architecture information
49 | try {
50 | processorArchInfo = ProcessorArch.getProcessorArchInformation();
51 | } catch (Exception e) {
52 | System.err.println("failed to obtain processor architecture information.");
53 | e.printStackTrace();
54 | }
55 | // Printing the processor architecture information
56 | System.out.println(processorArchInfo);
57 | }
58 |
59 | @JsonIgnoreProperties(ignoreUnknown = true)
60 | public static class Builder {
61 | private double cpuLoad = DEFAULT_CPU_LOAD;
62 | private int duration = DEFAULT_DURATION;
63 |
64 | public Builder withConfig(String configFilePath) throws IOException {
65 | ObjectMapper mapper = new ObjectMapper(new YAMLFactory());
66 | Builder builder;
67 | try {
68 | builder = mapper.readValue(new File(configFilePath), Builder.class);
69 | } catch (IOException exception) {
70 | throw new IOException("failed to open load generator config file", exception);
71 | }
72 |
73 | return builder;
74 | }
75 |
76 | public Builder() { }
77 |
78 | public void setCpuLoad(double cpuLoad) {
79 | this.cpuLoad = cpuLoad;
80 | }
81 | public void setDuration(int duration) {
82 | this.duration = duration;
83 | }
84 |
85 | public ConstantCPULoad build() {
86 | return new ConstantCPULoad(cpuLoad, duration);
87 | }
88 | }
89 |
90 | private ConstantCPULoad(double cpuLoad, int duration) {
91 | this.cpuLoad = cpuLoad;
92 | this.duration = duration;
93 | }
94 |
95 | // Generate constant CPU Load of the configured amount and maintain that
96 | // load for the configured duration.
97 | @Override
98 | public void execute() {
99 | System.out.println(String.format("Generating %f %% CPU load for %d seconds",
100 | cpuLoad, duration));
101 | try {
102 | CPULoad.createLoad(processorArchInfo.getNumCores(),
103 | processorArchInfo.getNumThreadsPerCore(),
104 | cpuLoad,
105 | duration,
106 | false,
107 | 0);
108 | } catch (InterruptedException e) {
109 | System.err.println("threads generating constant cpu load interrupted!");
110 | e.printStackTrace();
111 | }
112 | System.out.println("Done generating CPU load!");
113 | }
114 | }
115 |
--------------------------------------------------------------------------------
/src/main/java/loadgenerator/strategies/factory/SimpleStrategyFactory.java:
--------------------------------------------------------------------------------
1 | /**
2 | * MIT License
3 | *
4 | * Copyright (c) 2019 PRADYUMNA KAUSHIK
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | package loadgenerator.strategies.factory;
25 |
26 | import java.io.IOException;
27 | import java.util.Objects;
28 |
29 | import loadgenerator.strategies.LoadGenerationStrategyI;
30 | import loadgenerator.strategies.ConstIncreaseCPULoad;
31 | import loadgenerator.strategies.ConstIncreaseLoadAverage;
32 | import loadgenerator.strategies.CPULoadGeneratorWithMemoryPressure;
33 | import loadgenerator.strategies.ConstantCPULoad;
34 |
35 | public final class SimpleStrategyFactory implements SimpleStrategyFactoryI {
36 |
37 | private enum LoadType {
38 | CPU_LOAD("cpuload", "cpuload_config.yaml"),
39 | LOAD_AVERAGE("loadaverage", "loadaverage_config.yaml"),
40 | CPU_LOAD_WITH_MEMORY_PRESSURE("cpuload_memorypressure",
41 | "cpuload_memorypressure_config.yaml"),
42 | CONSTANT_CPU_LOAD("const_cpuload", "const_cpuload_config.yaml");
43 |
44 | private final String name;
45 | private final String configFilename;
46 |
47 | LoadType(final String s, final String configFilename) {
48 | name = s;
49 | this.configFilename = configFilename;
50 | }
51 |
52 | String getName() {
53 | return name;
54 | }
55 |
56 | String getConfigFilename() {
57 | return configFilename;
58 | }
59 |
60 | static boolean isValid(final String s) {
61 | for (LoadType loadType : values()) {
62 | if (loadType.getName().equals(s)) {
63 | return true;
64 | }
65 | }
66 | return false;
67 | }
68 |
69 | static LoadType forName(final String s) {
70 | for (LoadType loadType : values()) {
71 | if (loadType.getName().equals(s)) {
72 | return loadType;
73 | }
74 | }
75 | return null;
76 | }
77 | }
78 |
79 | private static final String PROJECT_ROOT = System.getProperty("user.dir");
80 | private static final String CONFIGS_DIRECTORY = "configs";
81 |
82 | @Override
83 | public LoadGenerationStrategyI getLoadGenerationStrategy(final String loadType)
84 | throws UnsupportedLoadTypeException, IOException {
85 |
86 | if (!LoadType.isValid(loadType)) {
87 | throw new UnsupportedLoadTypeException("failed to create load generation strategy: "
88 | + "unsupported load type");
89 | }
90 |
91 | switch (Objects.requireNonNull(LoadType.forName(loadType))) {
92 | case CPU_LOAD:
93 | return new ConstIncreaseCPULoad.Builder()
94 | .withConfig(PROJECT_ROOT
95 | + "/"
96 | + CONFIGS_DIRECTORY
97 | + "/"
98 | + LoadType.CPU_LOAD.getConfigFilename())
99 | .build();
100 | case LOAD_AVERAGE:
101 | return new ConstIncreaseLoadAverage.Builder()
102 | .withConfig(PROJECT_ROOT
103 | + "/"
104 | + CONFIGS_DIRECTORY
105 | + "/"
106 | + LoadType.LOAD_AVERAGE.getConfigFilename())
107 | .build();
108 | case CPU_LOAD_WITH_MEMORY_PRESSURE:
109 | return new CPULoadGeneratorWithMemoryPressure.Builder()
110 | .withConfig(PROJECT_ROOT
111 | + "/"
112 | + CONFIGS_DIRECTORY
113 | + "/"
114 | + LoadType.CPU_LOAD_WITH_MEMORY_PRESSURE.getConfigFilename())
115 | .build();
116 | case CONSTANT_CPU_LOAD:
117 | return new ConstantCPULoad.Builder()
118 | .withConfig(PROJECT_ROOT
119 | + "/"
120 | + CONFIGS_DIRECTORY
121 | + "/"
122 | + LoadType.CONSTANT_CPU_LOAD.getConfigFilename())
123 | .build();
124 | default:
125 | return null;
126 | }
127 | }
128 | }
129 |
--------------------------------------------------------------------------------
/src/main/java/loadgenerator/strategies/ConstIncreaseCPULoad.java:
--------------------------------------------------------------------------------
1 | /**
2 | * MIT License
3 | *
4 | * Copyright (c) 2019 PRADYUMNA KAUSHIK
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | package loadgenerator.strategies;
25 |
26 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
27 | import com.fasterxml.jackson.databind.ObjectMapper;
28 | import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
29 |
30 | import java.io.File;
31 | import java.io.IOException;
32 |
33 | import loadgenerator.util.CPULoad;
34 | import loadgenerator.util.ProcessorArch;
35 | import loadgenerator.entities.ProcessorArchInfo;
36 |
37 | public class ConstIncreaseCPULoad implements LoadGenerationStrategyI {
38 | // Setting the default step size for increase in CPU load to be 10%.
39 | private static final double DEFAULT_STEP_SIZE = 0.1;
40 | // Setting default duration for the load to be 4sec.
41 | private static final int DEFAULT_DURATION = 4000;
42 | // Default number of segments for creating alternating CPU load.
43 | private static final int DEFAULT_ALT_SEGMENTS = 2;
44 | private static ProcessorArchInfo processorArchInfo = null;
45 |
46 | // Non-defaults.
47 | private double stepSize = DEFAULT_STEP_SIZE;
48 | private int duration = DEFAULT_DURATION;
49 | private boolean isAlt = false;
50 | private int segments = DEFAULT_ALT_SEGMENTS;
51 |
52 | static {
53 | // Retrieving the processor architecture information
54 | try {
55 | processorArchInfo = ProcessorArch.getProcessorArchInformation();
56 | } catch (Exception e) {
57 | System.err.println("failed to obtain processor architecture information.");
58 | e.printStackTrace();
59 | }
60 | // Printing the processor architecture information
61 | System.err.println(processorArchInfo);
62 | }
63 |
64 | public static class Builder {
65 | private double stepSize = DEFAULT_STEP_SIZE;
66 | private int duration = DEFAULT_DURATION;
67 | private boolean isAlt = false;
68 |
69 | private int segments = DEFAULT_ALT_SEGMENTS;
70 |
71 | public Builder withConfig(String configFilePath) throws IOException {
72 | ObjectMapper mapper = new ObjectMapper(new YAMLFactory());
73 | Builder builder;
74 | try {
75 | builder = mapper.readValue(new File(configFilePath), Builder.class);
76 | } catch (IOException exception) {
77 | throw new IOException("failed to open load generator config file", exception);
78 | }
79 |
80 | return builder;
81 | }
82 |
83 | public Builder() {
84 | }
85 |
86 | public void setStepSize(double stepSize) {
87 | this.stepSize = stepSize;
88 | }
89 | public void setDuration(int duration) {
90 | this.duration = duration;
91 | }
92 | public void setIsAlt(boolean isAlt) {
93 | this.isAlt = isAlt;
94 | }
95 | public void setSegments(int segments) {
96 | this.segments = segments;
97 | }
98 |
99 | public ConstIncreaseCPULoad build() {
100 | return new ConstIncreaseCPULoad(stepSize, duration, isAlt, segments);
101 | }
102 |
103 | }
104 |
105 | private ConstIncreaseCPULoad(double stepSize, int duration, boolean isAlt, int segments) {
106 | this.stepSize = stepSize;
107 | this.duration = duration;
108 | this.isAlt = isAlt;
109 | this.segments = segments;
110 | }
111 |
112 | // Constantly increase the CPU load in steps = stepSize.
113 | // The CPU load is going to be simulated for the specified duration.
114 | @Override
115 | public void execute() {
116 | // Time for each a particular CPU load needs to be maintained for.
117 | long currentTime = System.currentTimeMillis();
118 | for (double load = stepSize; load <= 1.0; load += stepSize) {
119 | System.err.println("CPU load changing to " + load);
120 | try {
121 | CPULoad.createLoad(processorArchInfo.getNumCores(),
122 | processorArchInfo.getNumThreadsPerCore(),
123 | load,
124 | duration,
125 | isAlt,
126 | segments);
127 | } catch (InterruptedException e) {
128 | System.err.println("interrupted! Next load change will happen sooner than you think.");
129 | e.printStackTrace();
130 | }
131 | }
132 | }
133 | }
134 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # System Load Generator
2 | Generate different kinds of system load.
3 |
4 | ## System Requirements
5 | 1. Java version 1.8+.
6 | 2. Gradle version 6.3.
7 |
8 | ### Compile
9 | Run `gradle build` to compile the source code.
10 |
11 | ### Run
12 | Run `gradle run` followed by command line arguments that you want to specify.
4 | * Copyright (c) 2019 PRADYUMNA KAUSHIK
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | package loadgenerator.strategies;
25 |
26 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
27 | import com.fasterxml.jackson.databind.ObjectMapper;
28 | import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
29 |
30 | import java.io.File;
31 | import java.io.IOException;
32 |
33 | import loadgenerator.util.LoadAverage;
34 | import loadgenerator.util.ProcessorArch;
35 | import loadgenerator.entities.ProcessorArchInfo;
36 |
37 | import java.util.concurrent.ExecutionException;
38 |
39 | public class ConstIncreaseLoadAverage implements LoadGenerationStrategyI {
40 | // Default value for 1min load average on each core.
41 | // This means that we would start with (START_LOAD_AVERAGE_CORE * numCores) number of threads to be always running.
42 | private static final double START_LOAD_AVERAGE_CORE;
43 |
44 | // Setting default step size for load average to be 20%.
45 | // This means that every minute, the number of running threads would be increased by (0.2 * numCores).
46 | // For example, on a 10 core machine,
47 | // There would be 0 thread running in the first minute.
48 | // There would be 2 threads running in parallel in the second minute.
49 | // There would be 4 threads running in parallel in the third minut and so on.
50 | private static final double STEP_SIZE = 0.2;
51 |
52 | // Setting default final value for 1min load average for each core to be 10 (total 1min load_avg = 10 * numCores).
53 | // This means that load would be increased until there are 10 processes either running or waiting to be run on
54 | // each core for the minute.
55 | private static final double LOAD_AVERAGE_LIMIT_CORE = 10.0;
56 |
57 | // Information regarding the number of cores and the number of virtual CPUs available.
58 | private static ProcessorArchInfo procArchInfo = null;
59 |
60 | // Non-Defaults.
61 | private final double startLoadAvgCore;
62 | private final double stepSize;
63 |
64 | static {
65 | // Retrieving the processor architecture information.
66 | try {
67 | procArchInfo = ProcessorArch.getProcessorArchInformation();
68 | } catch (Exception e) {
69 | System.err.println("failed to obtain processor architecture information.");
70 | e.printStackTrace();
71 | }
72 | // Printing the processor architecture information.
73 | System.err.println(procArchInfo);
74 |
75 | // Initializing default value for START_LOAD_AVERAGE_CORE.
76 | START_LOAD_AVERAGE_CORE = 1.0 / procArchInfo.getNumCores();
77 | }
78 |
79 | @JsonIgnoreProperties(ignoreUnknown = true)
80 | public static class Builder {
81 | private double startLoadAvgCore = START_LOAD_AVERAGE_CORE;
82 | private double stepSize = STEP_SIZE;
83 |
84 | public Builder withConfig(String configFilePath) throws IOException {
85 | ObjectMapper mapper = new ObjectMapper(new YAMLFactory());
86 | Builder builder;
87 | try {
88 | builder = mapper.readValue(new File(configFilePath), Builder.class);
89 | } catch (IOException exception) {
90 | throw new IOException("failed to open load average generator config file", exception);
91 | }
92 |
93 | return builder;
94 | }
95 |
96 | public Builder() {
97 | }
98 |
99 | public void setStepSize(double stepSize) { this.stepSize = stepSize; }
100 | public void setStartLoadAvgCore(double startLoadAvgCore) { this.startLoadAvgCore = startLoadAvgCore; }
101 |
102 | public ConstIncreaseLoadAverage build() {
103 | return new ConstIncreaseLoadAverage(startLoadAvgCore, stepSize);
104 | }
105 | }
106 |
107 | private ConstIncreaseLoadAverage(double startLoadAvgCore, double stepSize) {
108 | this.startLoadAvgCore = startLoadAvgCore;
109 | this.stepSize = stepSize;
110 | }
111 |
112 | @Override
113 | public void execute() {
114 | long duration = 60000; // 1min.
115 | long currentTime = System.currentTimeMillis();
116 | double currentLoadAvgCore = startLoadAvgCore;
117 | while (currentLoadAvgCore <= LOAD_AVERAGE_LIMIT_CORE) {
118 | int totalNumCores = procArchInfo.getNumCores();
119 | int numThreadsToCreate = (int) Math.floor((currentLoadAvgCore * totalNumCores) + 0.5);
120 | System.out.println("Creating load...");
121 | System.out.println("load average for next minute = " + numThreadsToCreate);
122 | System.out.println();
123 |
124 | try {
125 | // Only if positive load.
126 | if (currentLoadAvgCore != 0) {
127 | LoadAverage.createLoad(numThreadsToCreate, duration);
128 | }
129 | // Thread.sleep(duration);
130 | } catch (InterruptedException | ExecutionException ie) {
131 | System.err.println((duration / 1000) + "second wait bas been interrupted!"
132 | + "Next load change will happen sooner than you think.");
133 | }
134 | currentLoadAvgCore += stepSize;
135 | }
136 | }
137 | }
138 |
--------------------------------------------------------------------------------
/src/main/java/loadgenerator/strategies/CPULoadGeneratorWithMemoryPressure.java:
--------------------------------------------------------------------------------
1 | /**
2 | * MIT License
3 | *
4 | * Copyright (c) 2019 PRADYUMNA KAUSHIK
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | package loadgenerator.strategies;
25 |
26 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
27 | import com.fasterxml.jackson.databind.ObjectMapper;
28 | import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
29 |
30 | import java.io.File;
31 | import java.io.IOException;
32 | import java.util.Locale;
33 | import java.util.Random;
34 |
35 | import loadgenerator.util.ProcessorArch;
36 | import loadgenerator.entities.ProcessorArchInfo;
37 |
38 | public class CPULoadGeneratorWithMemoryPressure implements LoadGenerationStrategyI {
39 |
40 | private final int minCpuLoadPercentage;
41 | private final int maxCpuLoadPercentage;
42 | private final int ramUsageBytes;
43 |
44 | @JsonIgnoreProperties(ignoreUnknown = true)
45 | public static class Builder {
46 | private int minCpuLoadPercentage;
47 | private int maxCpuLoadPercentage;
48 | private int ramUsageBytes;
49 |
50 | public Builder withConfig(String configFilePath) throws IOException {
51 | ObjectMapper mapper = new ObjectMapper(new YAMLFactory());
52 | Builder builder;
53 | try {
54 | builder = mapper.readValue(new File(configFilePath), Builder.class);
55 | } catch (IOException exception) {
56 | throw new IOException("failed to open cpu load with memory pressure generator config file", exception);
57 | }
58 |
59 | return builder;
60 | }
61 |
62 | public Builder() {
63 | }
64 |
65 | public void setMinCpuLoadPercentage(int minCpuLoadPercentage) {
66 | this.minCpuLoadPercentage = minCpuLoadPercentage;
67 | }
68 | public void setMaxCpuLoadPercentage(int maxCpuLoadPercentage) {
69 | this.maxCpuLoadPercentage = maxCpuLoadPercentage;
70 | }
71 | public void setRamUsageBytes(int ramUsageBytes) {
72 | this.ramUsageBytes = ramUsageBytes;
73 | }
74 |
75 | public CPULoadGeneratorWithMemoryPressure build() {
76 | return new CPULoadGeneratorWithMemoryPressure(minCpuLoadPercentage, maxCpuLoadPercentage, ramUsageBytes);
77 | }
78 | }
79 |
80 | private CPULoadGeneratorWithMemoryPressure(int minCpuLoadPercentage, int maxCpuLoadPercentage, int ramUsageBytes) {
81 | this.minCpuLoadPercentage = minCpuLoadPercentage;
82 | this.maxCpuLoadPercentage = maxCpuLoadPercentage;
83 | this.ramUsageBytes = ramUsageBytes;
84 |
85 | }
86 |
87 | @Override
88 | public void execute() {
89 | ProcessorArchInfo procArchInfo = null;
90 | try {
91 | procArchInfo = ProcessorArch.getProcessorArchInformation();
92 | } catch (Exception e) {
93 | e.printStackTrace();
94 | System.exit(1);
95 | }
96 |
97 | int numCores = procArchInfo.getNumThreadsPerCore();
98 | int numThreadsPerCore = procArchInfo.getNumThreadsPerCore();
99 | int threadsToCreate = numCores * numThreadsPerCore;
100 |
101 | byte[] memory = new byte[ramUsageBytes / threadsToCreate];
102 | for (int thread = 0; thread < threadsToCreate; thread++) {
103 | new BusyThread("Thread-" + thread, minCpuLoadPercentage, maxCpuLoadPercentage, memory).start();
104 | }
105 | }
106 |
107 | /**
108 | * Thread that actually generates the given load
109 | * @author Sriram
110 | */
111 | private static class BusyThread extends Thread {
112 | private final Random random;
113 | private final int minCpuLoadPercentage;
114 | private final int maxCpuLoadPercentage;
115 | private final byte[] memory;
116 |
117 | public BusyThread(String name, int minCpuLoadPercentage, int maxCpuLoadPercentage, byte[] memory) {
118 | super(name);
119 |
120 | this.random = new Random(name.hashCode() + System.currentTimeMillis());
121 | this.minCpuLoadPercentage = minCpuLoadPercentage;
122 | this.maxCpuLoadPercentage = maxCpuLoadPercentage;
123 | this.memory = memory;
124 | }
125 |
126 | /**
127 | * Generates the load when run
128 | */
129 | @Override
130 | public void run() {
131 |
132 | final int cpuPressureRange = maxCpuLoadPercentage - minCpuLoadPercentage;
133 |
134 | try {
135 | System.out.println(String.format(Locale.US, "Thread %s starting with CPU pressure [%d-%d] and %d bytes",
136 | getName(), minCpuLoadPercentage, maxCpuLoadPercentage, memory.length));
137 | Thread.sleep(cpuPressureRange);
138 |
139 | while (true) {
140 | final int duration = minCpuLoadPercentage + random.nextInt(cpuPressureRange);
141 | final long startTime = System.currentTimeMillis();
142 | long currentDuration = (System.currentTimeMillis() - startTime);
143 | while (currentDuration < duration) {
144 | final int cellToAccess = random.nextInt(memory.length);
145 | final byte previousValue = memory[cellToAccess];
146 | memory[cellToAccess] = (byte) (previousValue + 1);
147 |
148 | currentDuration = (System.currentTimeMillis() - startTime);
149 | }
150 | if (currentDuration > 100) {
151 | currentDuration = 100;
152 | }
153 | Thread.sleep(100 - currentDuration);
154 | }
155 | } catch (InterruptedException e) {
156 | System.out.println(String.format(Locale.US, "Thread %s failed with %s", getName(), e.getMessage()));
157 | e.printStackTrace();
158 | }
159 | }
160 | }
161 |
162 | }
163 |
--------------------------------------------------------------------------------
/src/main/java/loadgenerator/util/CPULoad.java:
--------------------------------------------------------------------------------
1 | /**
2 | * MIT License
3 | *
4 | * Copyright (c) 2019 PRADYUMNA KAUSHIK
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | package loadgenerator.util;
25 |
26 | import java.util.List;
27 | import java.util.ArrayList;
28 |
29 | /**
30 | * Generates Load on the CPU by keeping it busy for the given load percentage
31 | * @author Sriram
32 | * @author Pradyumna Kaushik
33 | */
34 | public class CPULoad {
35 | /**
36 | * Function to be called by a wrapper
37 | * A wrapper could be a program that determines the requirements such as,
38 | * Number of cores
39 | * Number of threads per core, etc
40 | * The wrapper would then pass those values so as to be able to create the requried amount of load.
41 | * @param numCore Number of cores
42 | * @param numThreadsPerCore Number of threads per core
43 | * @param load % CPU load to generate
44 | * @param duration Duration for which this load has to be maintained
45 | * @param isAlt Whether we need to create an alternating load. An alternating load is one where we
46 | * alternate between running and sleeping, within the load duration, to generate the required CPU load.
47 | * @param segments Number of alternating segments, for an alternating CPU load, for the specified duration.
48 | */
49 | public static void createLoad(int numCore, int numThreadsPerCore, double load,
50 | long duration, boolean isAlt, int segments) throws InterruptedException {
51 | List
13 | The following command line arguments are supported.
14 | 1. `--help` - Display the help string.
15 | 2. `--load-type