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

NH-37575 Move benchmark job to push workflow #240

Merged
merged 5 commits into from
Jul 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
73 changes: 73 additions & 0 deletions .github/workflows/codeql.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
# For most projects, this workflow file will not need changing; you simply need
# to commit it to your repository.
#
# You may wish to alter this file to override the set of languages analyzed,
# or to provide custom queries or build logic.
#
# ******** NOTE ********
# We have attempted to detect the languages in your repository. Please check
# the `language` matrix defined below to confirm you have the correct set of
# supported CodeQL languages.
#
name: "CodeQL"

on:
push:
branches: [ "main" ]
pull_request:
# The branches below must be a subset of the branches above
branches: [ "main" ]
schedule:
- cron: '0 7 * * 1'

jobs:
analyze:
name: Analyze
runs-on: ubuntu-latest
permissions:
actions: read
contents: read
security-events: write

strategy:
fail-fast: false
matrix:
language: [ 'java' ]
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
# Use only 'java' to analyze code written in Java, Kotlin or both
# Use only 'javascript' to analyze code written in JavaScript, TypeScript or both
# Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support

steps:
- name: Checkout repository
uses: actions/checkout@v4

# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v3
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
# By default, queries listed here will override any specified in a config file.
# Prefix the list here with "+" to use these queries and those in the config file.

# Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
queries: +security-extended,security-and-quality

# Autobuild fails so use custom build steps
- name: Set up JDK 17
uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'temurin'

- name: Setup Gradle
uses: gradle/actions/setup-gradle@v3

- name: Build with Gradle
run: ./gradlew build -x test

- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v3
with:
category: "/language:${{matrix.language}}"
40 changes: 40 additions & 0 deletions .github/workflows/push.yml
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ jobs:
docker buildx build --tag $IMAGE_ID_XK6 --push xk6/

- name: Docker logout
if: always()
run: docker logout

test:
Expand Down Expand Up @@ -190,6 +191,7 @@ jobs:
name: lambda-release-test

- name: Docker logout
if: always()
run: docker logout

lambda-publish-stage:
Expand Down Expand Up @@ -380,4 +382,42 @@ jobs:
name: release-test

- name: Docker logout
if: always()
run: docker logout

benchmark:
runs-on: ubuntu-latest
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
needs:
- s3-stage-upload
steps:
- uses: actions/checkout@v4

- name: Set up JDK 17
uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'temurin'

- name: Docker login
run: echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u $GITHUB_USERNAME --password-stdin

- name: Benchmark test
working-directory: benchmark
run: ./gradlew test

- uses: actions/upload-artifact@v4
with:
path: benchmark/results/release/summary.txt
name: benchmark-summary

- uses: actions/upload-artifact@v4
if: always()
with:
path: benchmark/build/reports/tests/test/
name: benchmark-test

- name: Docker logout
if: always()
run: docker logout
32 changes: 0 additions & 32 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -285,35 +285,3 @@ jobs:
with:
path: arns.txt
name: arns

benchmark:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Set up JDK 17
uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'temurin'

- name: Docker login
run: echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u $GITHUB_USERNAME --password-stdin

- name: Benchmark test
run: |
cd benchmark
./gradlew test

- uses: actions/upload-artifact@v4
with:
path: benchmark/results/release/summary.txt
name: benchmark-summary

- uses: actions/upload-artifact@v4
with:
path: benchmark/build/reports/tests/test/
name: benchmark-test

- name: Docker logout
run: docker logout
3 changes: 0 additions & 3 deletions CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
@@ -1,4 +1 @@
* @solarwinds-cloud/eng-apm-instrumentation

# for upcoming repo transfer, remove above one afterwards
* @solarwinds/eng-pub-apm-instrumentation
24 changes: 13 additions & 11 deletions benchmark/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
plugins {
id("java")
id("com.diffplug.spotless") version "6.1.2"
id("com.diffplug.spotless") version "6.25.0"
}

spotless {
java {
googleJavaFormat()
licenseHeaderFile(rootProject.file("../buildscripts/spotless.license.java"), "(package|import|public)")
target("src/**/*.java")
}
}
Expand All @@ -16,15 +15,18 @@ repositories {
}

dependencies {
testImplementation("org.testcontainers:testcontainers:1.16.2")
testImplementation("org.testcontainers:postgresql:1.15.3")
testImplementation("org.junit.jupiter:junit-jupiter-api:5.7.2")
testImplementation("org.junit.jupiter:junit-jupiter-params:5.7.2")
testImplementation("com.squareup.okhttp3:okhttp:4.9.1")
testImplementation("org.jooq:joox:1.6.2")
testImplementation("com.jayway.jsonpath:json-path:2.6.0")
testImplementation("com.fasterxml.jackson.core:jackson-databind:2.0.1")
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.7.2")
implementation(enforcedPlatform("org.junit:junit-bom:5.10.3"))

testImplementation("org.testcontainers:testcontainers:1.19.8")
testImplementation("org.testcontainers:postgresql:1.19.8")
testImplementation("org.junit.jupiter:junit-jupiter-api")
testImplementation("org.junit.jupiter:junit-jupiter-params")
testImplementation("com.squareup.okhttp3:okhttp:4.12.0")
testImplementation("org.jooq:joox:2.0.1")
testImplementation("com.jayway.jsonpath:json-path:2.9.0")
testImplementation("org.slf4j:slf4j-simple:2.0.13")

testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine")
}

tasks {
Expand Down
52 changes: 37 additions & 15 deletions benchmark/src/test/java/io/opentelemetry/OverheadTests.java
Original file line number Diff line number Diff line change
Expand Up @@ -40,19 +40,26 @@ public class OverheadTests {
private static GenericContainer<?> aoCollector;
private final NamingConventions namingConventions = new NamingConventions();
private final Map<String, Long> runDurations = new HashMap<>();
private static Set<String> verboseConfig = new HashSet<>(Arrays.asList(Strings.split(System.getenv("CONTAINER_LOGS") != null ? System.getenv("CONTAINER_LOGS") : "", '|')));
private static Set<String> verboseConfig =
new HashSet<>(
Arrays.asList(
Strings.split(
System.getenv("CONTAINER_LOGS") != null ? System.getenv("CONTAINER_LOGS") : "",
'|')));

@BeforeAll
static void setUp() {
collector = CollectorContainer.build(NETWORK);
collector.start();

aoCollector = AOTestCollectorContainer.build(NETWORK);
aoCollector.start();
}

@AfterAll
static void tearDown() {
collector.close();
aoCollector.close();
}

@TestFactory
Expand Down Expand Up @@ -102,14 +109,18 @@ void runAppOnce(TestConfig config, Agent agent) throws Exception {

if (verboseConfig.contains("all") || verboseConfig.contains("app")) {
String logs = petclinic.getLogs();
System.err.println(String.format("\n\n===============%s====================\n\n%s\n\n==============================="
, agent.getName(), logs));
System.err.println(
String.format(
"\n\n===============%s====================\n\n%s\n\n===============================",
agent.getName(), logs));
}

if (verboseConfig.contains("all") || verboseConfig.contains("collector")) {
String aoCollectorLogs = aoCollector.getLogs();
System.err.println(String.format("\n\n===============%s====================\n\n%s\n\n==============================="
, aoCollector.getDockerImageName(), aoCollectorLogs));
System.err.println(
String.format(
"\n\n===============%s====================\n\n%s\n\n===============================",
aoCollector.getDockerImageName(), aoCollectorLogs));
}
// This is required to get a graceful exit of the VM before testcontainers kills it forcibly.
// Without it, our jfr file will be empty.
Expand All @@ -134,22 +145,33 @@ private void startRecording(Agent agent, GenericContainer<?> petclinic) throws E
petclinic.execInContainer(command);
}

private void doWarmupPhase(TestConfig testConfig, GenericContainer<?> petclinic) throws IOException, InterruptedException {
System.out.println("Performing startup warming phase for " + testConfig.getWarmupSeconds() + " seconds...");
private void doWarmupPhase(TestConfig testConfig, GenericContainer<?> petclinic)
throws IOException, InterruptedException {
System.out.println(
"Performing startup warming phase for " + testConfig.getWarmupSeconds() + " seconds...");

// excluding the JFR recording from the warmup causes strange inconsistencies in the results
System.out.println("Starting disposable JFR warmup recording...");
String[] startCommand = {"jcmd", "1", "JFR.start", "settings=/app/overhead.jfc", "dumponexit=true", "name=warmup", "filename=warmup.jfr"};
String[] startCommand = {
"jcmd",
"1",
"JFR.start",
"settings=/app/overhead.jfc",
"dumponexit=true",
"name=warmup",
"filename=warmup.jfr"
};
petclinic.execInContainer(startCommand);

long deadline = System.currentTimeMillis() + TimeUnit.SECONDS.toMillis(testConfig.getWarmupSeconds());
while(System.currentTimeMillis() < deadline) {
long deadline =
System.currentTimeMillis() + TimeUnit.SECONDS.toMillis(testConfig.getWarmupSeconds());
while (System.currentTimeMillis() < deadline) {
GenericContainer<?> k6 =
new GenericContainer<>(DockerImageName.parse("loadimpact/k6"))
.withNetwork(NETWORK)
.withCopyFileToContainer(MountableFile.forHostPath("./k6"), "/app")
.withCommand("run", "-u", "5", "-i", "200", "/app/basic.js")
.withStartupCheckStrategy(new OneShotStartupCheckStrategy());
new GenericContainer<>(DockerImageName.parse("loadimpact/k6"))
.withNetwork(NETWORK)
.withCopyFileToContainer(MountableFile.forHostPath("./k6"), "/app")
.withCommand("run", "-u", "5", "-i", "200", "/app/basic.js")
.withStartupCheckStrategy(new OneShotStartupCheckStrategy());
k6.start();
}

Expand Down
12 changes: 7 additions & 5 deletions benchmark/src/test/java/io/opentelemetry/agents/Agent.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,13 @@ public class Agent {
"https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases/latest/download/opentelemetry-javaagent.jar";

public static final Agent NONE = new Agent("none", "no agent at all");
public static final Agent LATEST_RELEASE =
new Agent("latest", "latest mainstream release", OTEL_LATEST);
public static final Agent LATEST_SNAPSHOT =
new Agent("snapshot", "latest available snapshot version from main");
public static final Agent NH_LATEST_RELEASE = new Agent(LatestSolarwindsAgentResolver.useAOAgent ? "AO" : "NH", "latest Solarwinds agent");
public static final Agent OTEL_LATEST_RELEASE =
new Agent("OTEL-latest", "latest mainstream release", OTEL_LATEST);
public static final Agent OTEL_LATEST_SNAPSHOT =
new Agent("OTEL-snapshot", "latest available snapshot version from main");
public static final Agent SWO_SNAPSHOT_RELEASE =
new Agent("SWO-snapshot", "Snapshot Solarwinds agent");
public static final Agent SWO_GA_RELEASE = new Agent("SWO-ga", "GA Solarwinds agent");

private final String name;
private final String description;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,20 +19,26 @@
public class AgentResolver {

private final LatestAgentSnapshotResolver snapshotResolver = new LatestAgentSnapshotResolver();
private final LatestSolarwindsAgentResolver nighthawkAgentResolver = new LatestSolarwindsAgentResolver();
private final SnapshotResolver swoSnapshotResolver = new SnapshotResolver();
private final GaResolver swoGaResolver = new GaResolver();

public Optional<Path> resolve(Agent agent) throws Exception {
if (Agent.NONE.equals(agent)) {
return Optional.empty();
}
if (Agent.LATEST_SNAPSHOT.equals(agent)) {

if (Agent.OTEL_LATEST_SNAPSHOT.equals(agent)) {
return snapshotResolver.resolve();
} else if (Agent.NH_LATEST_RELEASE.equals(agent)) {
return nighthawkAgentResolver.resolve();
} else if (Agent.SWO_SNAPSHOT_RELEASE.equals(agent)) {
return swoSnapshotResolver.resolve();
} else if (Agent.SWO_GA_RELEASE.equals(agent)) {
return swoGaResolver.resolve();
}

if (agent.hasUrl()) {
return Optional.of(downloadAgent(agent.getUrl()));
}

throw new IllegalArgumentException("Unknown agent: " + agent);
}

Expand Down
Loading