Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Internship] Benchmarking remote execution #346

Open
wants to merge 24 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 10 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
c6ed526
Added managed cyclical dependency example
NicolasHuertas Sep 9, 2024
f8ee4ff
Refractored folder and fixed run error
NicolasHuertas Sep 14, 2024
13f6962
Create README.md
NicolasHuertas Sep 15, 2024
4fcc28b
Program now reads through an input file
NicolasHuertas Sep 16, 2024
9f9d3df
Update README.md
NicolasHuertas Sep 16, 2024
8cd1877
Added varying input example
NicolasHuertas Oct 4, 2024
5698dd2
Merge branch 'main' of https://github.com/NicolasHuertas/example
NicolasHuertas Oct 4, 2024
33ce4db
Example using inputs from a genrule
NicolasHuertas Oct 6, 2024
b1c8d09
fixed genfile path error
NicolasHuertas Oct 6, 2024
2905e21
Added biinary input example
NicolasHuertas Oct 6, 2024
0a4819a
changed depedency structure
NicolasHuertas Oct 23, 2024
7ef5e68
reverting changes on .bazelrc
NicolasHuertas Oct 25, 2024
780abf3
Merge remote-tracking branch 'origin/main'
NicolasHuertas Dec 3, 2024
282ff15
Refractored internship folder and added benchmark script
NicolasHuertas Dec 3, 2024
1f4c666
Deleted unremoved occurrences of internship in BUILD files
NicolasHuertas Dec 3, 2024
db9f94a
Delete example.iml
NicolasHuertas Dec 3, 2024
422e14c
Deleted profile.json and fixed comment formatting
NicolasHuertas Dec 5, 2024
0cbe62a
Merge branch 'main' of https://github.com/EngFlow/example
NicolasHuertas Dec 5, 2024
a382758
Removed profile.json and fixed comment formatting
NicolasHuertas Dec 5, 2024
c7ccbf2
Merge branch 'internship' of https://github.com/EngFlow/example into …
NicolasHuertas Dec 5, 2024
0d883c5
Delete profile1.json
NicolasHuertas Dec 5, 2024
a288f24
Delete profile.json
NicolasHuertas Dec 5, 2024
3a6e55a
Added usage comments to the benchmark script
NicolasHuertas Dec 12, 2024
f286be0
Merge branch 'internship' of https://github.com/EngFlow/example into …
NicolasHuertas Dec 12, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions example.iml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is this file? Do things work without it? We should not need config files like this

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems to be a file created by IntelliJ to keep the module configuration. The program should work without it.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lets please remove this file.

<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/java" isTestSource="false" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>
13 changes: 13 additions & 0 deletions java/com/engflow/internship/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Example Projects for Performance Testing

## Overview

Welcome to the `internship` folder of the EngFlow examples repository. This folder contains a set of example projects designed to evaluate and benchmark the performance of EngFlow's remote execution and caching services. These projects aim to provide a diverse range of test cases with varying input sizes, numbers of inputs, and execution times. The goal is to generate performance data that can help in understanding how different factors affect the performance of remote build optimization services.

## Purpose

The primary objectives of these example projects are to:

1. **Generate Performance Data**: Create examples with varying complexity to test and gather performance data for EngFlow’s remote caching and execution services.
2. **Benchmark Analysis**: Compare the performance of local versus remote execution and caching to evaluate the efficiency and effectiveness of the service.
3. **Support Automation Development**: Contribute to the development of automation algorithms for resource assignment by providing valuable data on how the size and nature of the builds impact performance.
32 changes: 32 additions & 0 deletions java/com/engflow/internship/binaryinput/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
load("@rules_java//java:defs.bzl", "java_binary", "java_library")

NUM_FILES = 10

#Main class
java_binary(
name = "main",
srcs = ["Main.java"],
main_class = "com.engflow.internship.binaryinput.Main",
deps = [
":genbinary"
],
args = [str(NUM_FILES)],
)

#Generates a number of java files based on the value of NUM_FILES
#Each file is named HelloX.java where X is the number of the file
#Each file contains a class with a greetNum method that prints "Hello" + the number of the file
[genrule(
name = "Hello" + str(x),
outs = ["Hello" + str(x) + ".java"],
cmd_bash = "echo 'package com.engflow.internship.binaryinput;" + "\n" +
"public class Hello" + str(x) +
" { public static void greetNum() { System.out.println(\"Hello " + str(x) + "\"); } }' > $@",
) for x in range(1,NUM_FILES+1)]

#Generates a java library that contains all the generated java files
java_library(
name = "genbinary",
srcs = [":Hello" + str(x) + ".java" for x in range(1,NUM_FILES+1)],
visibility = ["//visibility:public"],
)
21 changes: 21 additions & 0 deletions java/com/engflow/internship/binaryinput/Main.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.engflow.internship.binaryinput;

import java.lang.reflect.InvocationTargetException;

public class Main {
public static void main(String[] args) {
try {
// args[0] is the number of files to read
int numFiles = Integer.parseInt(args[0]);

// Load and run the greetNum method from each class
for(int i = 1; i <= numFiles; i++){
Class<?> clazz = Class.forName("com.engflow.internship.binaryinput.Hello" + i);
clazz.getMethod("greetNum").invoke(null);
}

} catch (ClassNotFoundException | InvocationTargetException | IllegalAccessException | NoSuchMethodException e) {
throw new RuntimeException(e);
}
}
}
52 changes: 52 additions & 0 deletions java/com/engflow/internship/binaryinput/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# Multiple Binary Input Example

## Overview

The goal of this example project is to test the performance of Engflow's remote execution and caching service based on the number of input binary files in the dependency graph. The project contains a `genrule` that generates a specified number of Java binaries for the `genbinary` Java library, which are then listed as dependencies in the main binary. The `Main.java` file loops through each generated class and calls its `greetNum` method.

## Project Structure

- `java/com/engflow/internship/binaryinput/Main.java`: Main class that dynamically loads and invokes methods from generated classes.
- `java/com/engflow/internship/binaryinput/BUILD`: Bazel build file for the `main` java binary and the `genbinary` library.

## Usage

To generate the test files, build the `genbinary` library using the `genrule`:
```sh
bazel build //java/com/engflow/internship/binaryinput:genbinary
```

Then, the program can be run with the following command:
```sh
bazel run //java/com/engflow/internship/binaryinput:main
```

## How It Works

1. **Generation of Java Binaries:**
- The `genrule` in the `BUILD` file generates a specified number of Java classes (`Hello1.java`, `Hello2.java`, ..., `HelloN.java`).
- Each generated class contains a `greetNum` method that prints a unique message.

2. **Main Class Execution:**
- The `Main.java` file in `binaryinput` dynamically loads each generated class using reflection.
- It then invokes the `greetNum` method of each class, printing the corresponding message.

## Configuration

The number of generated files is controlled by the `NUM_FILES` variable in the `BUILD` file of the `binaryinput` package. Modify this variable to change the number of generated classes and observe the performance impact on Engflow's remote execution and caching service.

## Example

To generate and run the program with 10 input binary files:

1. Set `NUM_FILES` to 10 in `java/com/engflow/internship/binaryinput/BUILD`.
2. Build the `genbinary` library:
```sh
bazel build //java/com/engflow/internship/binaryinput:genbinary
```
3. Run the `main` binary:
```sh
bazel run //java/com/engflow/internship/binaryinput:main
```

This will generate 10 Java classes, build the `genbinary` library, and run the `main` binary, which will print messages from each generated class.
36 changes: 36 additions & 0 deletions java/com/engflow/internship/cycleexample/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Cyclical Dependency Example

## Overview

This project is designed to evaluate and benchmark the performance of EngFlow's remote execution and caching services. It specifically focuses on testing scenarios involving cyclical-like structures in the dependency graph, which are handled through interfaces and constructor injection.

## Purpose

The primary objectives of this project are to:

1. **Generate Performance Data**: Create examples with cyclical-like dependencies to test and gather performance data for EngFlow’s remote caching and execution services.
2. **Benchmark Analysis**: Compare the performance of local versus remote execution and caching to evaluate the efficiency and effectiveness of the service.
3. **Support Automation Development**: Contribute to the development of automation algorithms for resource assignment by providing valuable data on how cyclical dependencies impact performance.

## Project Structure

The project is organized into several packages, each representing different components of the cyclical dependency example:

- `class_a`: Contains `ClassA` which depends on `ClassB` through an interface.
- `class_b`: Contains `ClassB` which implements `InterfaceB` and depends on `ClassC`.
- `class_c`: Contains `ClassC` which implements `InterfaceA` and can be initialized with a reference to `ClassA`.
- `interface_a`: Defines the interface `InterfaceA` implemented by `ClassA` and `ClassC`.
- `interface_b`: Defines the interface `InterfaceB` implemented by `ClassB`.
- `main`: Contains the `Main` class which processes the input file.
- `input`: Contains the input text file used by the `Main` class.

## How the Program Works

The program takes a text input file and recursively prints each word with each class (`ClassA` prints a word, then `ClassB`, and so on) until the string is empty. The input file should be specified in the `data` attribute of the `java_binary` rule in the `BUILD` file.

## How to Run Tests

To run the tests and gather performance data, use the following Bazel command:

```sh
bazel test //java/com/engflow/internship/cycleexample/class_a:class_a_test
22 changes: 22 additions & 0 deletions java/com/engflow/internship/cycleexample/class_a/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package(default_visibility = ["//visibility:public"])

java_library(
name = "class_a",
srcs = ["ClassA.java"],
deps = [
"//java/com/engflow/internship/cycleexample/class_b",
"//java/com/engflow/internship/cycleexample/interface_a",
],
)

java_test(
name = "class_a_test",
srcs = ["ClassATest.java"],
test_class = "com.engflow.internship.cycleexample.class_a.ClassATest",
deps = [
":class_a",
"//java/com/engflow/internship/cycleexample/class_b:class_b",
"//java/com/engflow/internship/cycleexample/class_c:class_c",
"//java/com/engflow/internship/cycleexample/interface_a:interface_a",
],
)
31 changes: 31 additions & 0 deletions java/com/engflow/internship/cycleexample/class_a/ClassA.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package com.engflow.internship.cycleexample.class_a;

import com.engflow.internship.cycleexample.class_b.ClassB;
import com.engflow.internship.cycleexample.interface_a.InterfaceA;

public class ClassA implements InterfaceA {
private ClassB classB;

public ClassA(ClassB classB) {
this.classB = classB;
}

@Override
public void methodA(String input) {
// If the input is null or empty, return immediately
if (input == null || input.isEmpty()) {
return;
}

//Find the index of the first space character in the input string.
int spaceIndex = input.indexOf(' ');
//Extract the word from the beginning of the input string up to the space character.
String word = (spaceIndex == -1) ? input : input.substring(0, spaceIndex);
//Extract the remaining part of the input string after the space character.
String remaining = (spaceIndex == -1) ? "" : input.substring(spaceIndex + 1);

//Print the word extracted from the input string.
System.out.println("ClassA: " + word);
classB.methodB(remaining);
}
}
42 changes: 42 additions & 0 deletions java/com/engflow/internship/cycleexample/class_a/ClassATest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package com.engflow.internship.cycleexample.class_a;

import com.engflow.internship.cycleexample.class_b.ClassB;
import com.engflow.internship.cycleexample.class_c.ClassC;
import org.junit.Test;
import static org.junit.Assert.assertTrue;

public class ClassATest {
private static class TestClassB extends ClassB {
boolean methodBCalled = false;

public TestClassB(ClassC classC) {
super(classC);
}

@Override
public void methodB(String input) {
methodBCalled = true;
}
}

@Test
public void testMethodA() {
// Create a ClassC instance with a null ClassA object
ClassC classC = new ClassC(null);

// Create a TestClassB instance with the ClassC object
TestClassB testClassB = new TestClassB(classC);

// Create a new ClassA instance with the TestClassB object
ClassA classA = new ClassA(testClassB);

// Properly initialize classC with classA
classC.setClassA(classA);

// Call methodA on classA with a sample input
classA.methodA("sample input");

// Verify that methodB on the TestClassB was called
assertTrue(testClassB.methodBCalled);
}
}
21 changes: 21 additions & 0 deletions java/com/engflow/internship/cycleexample/class_b/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package(default_visibility = ["//visibility:public"])

java_library(
name = "class_b",
srcs = ["ClassB.java"],
deps = [
"//java/com/engflow/internship/cycleexample/class_c",
"//java/com/engflow/internship/cycleexample/interface_b",
],
)

java_test(
name = "class_b_test",
srcs = ["ClassBTest.java"],
test_class = "com.engflow.internship.cycleexample.class_b.ClassBTest",
deps = [
":class_b",
"//java/com/engflow/internship/cycleexample/class_c:class_c",
"//java/com/engflow/internship/cycleexample/interface_b:interface_b",
],
)
31 changes: 31 additions & 0 deletions java/com/engflow/internship/cycleexample/class_b/ClassB.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package com.engflow.internship.cycleexample.class_b;

import com.engflow.internship.cycleexample.class_c.ClassC;
import com.engflow.internship.cycleexample.interface_b.InterfaceB;

public class ClassB implements InterfaceB {
private ClassC classC;

public ClassB(ClassC classC) {
this.classC = classC;
}

@Override
public void methodB(String input) {
// If the input is null or empty, return immediately
if (input == null || input.isEmpty()) {
return;
}

//Find the index of the first space character in the input string.
int spaceIndex = input.indexOf(' ');
//Extract the word from the beginning of the input string up to the space character.
String word = (spaceIndex == -1) ? input : input.substring(0, spaceIndex);
//Extract the remaining part of the input string after the space character.
String remaining = (spaceIndex == -1) ? "" : input.substring(spaceIndex + 1);

//Print the word extracted from the input string.
System.out.println("ClassB: " + word);
classC.methodA(remaining);
}
}
35 changes: 35 additions & 0 deletions java/com/engflow/internship/cycleexample/class_b/ClassBTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package com.engflow.internship.cycleexample.class_b;

import com.engflow.internship.cycleexample.class_c.ClassC;
import org.junit.Test;
import static org.junit.Assert.assertTrue;

public class ClassBTest {
private static class TestClassC extends ClassC {
boolean methodACalled = false;

public TestClassC() {
super(null);
}

@Override
public void methodA(String input) {
methodACalled = true;
}
}

@Test
public void testMethodB() {
// Create a TestClassC instance
TestClassC testClassC = new TestClassC();

// Create an instance of ClassB with the TestClassC object
ClassB classB = new ClassB(testClassC);

// Call methodB on classB
classB.methodB("Sample input");

// Verify that methodA on the TestClassC was called
assertTrue(testClassC.methodACalled);
}
}
20 changes: 20 additions & 0 deletions java/com/engflow/internship/cycleexample/class_c/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package(default_visibility = ["//visibility:public"])

java_library(
name = "class_c",
srcs = ["ClassC.java"],
visibility = ["//visibility:public"],
deps = [
"//java/com/engflow/internship/cycleexample/interface_a",
],
)

java_test(
name = "class_c_test",
srcs = ["ClassCTest.java"],
test_class = "com.engflow.internship.cycleexample.class_c.ClassCTest",
deps = [
":class_c",
"//java/com/engflow/internship/cycleexample/class_a:class_a",
],
)
Loading
Loading