diff --git a/.github/taurus-constraints.txt b/.github/taurus-constraints.txt new file mode 100644 index 0000000..a26bf0b --- /dev/null +++ b/.github/taurus-constraints.txt @@ -0,0 +1,5 @@ +# Pin Taurus to a known-good combination. +# bzt 1.16.49 currently resolves urwid>=3 and fails at runtime on +# `from urwid.decoration import Padding`. +bzt==1.16.40 +urwid==2.1.2 diff --git a/.github/workflows/ci-build.yaml b/.github/workflows/ci-build.yaml new file mode 100644 index 0000000..97fd439 --- /dev/null +++ b/.github/workflows/ci-build.yaml @@ -0,0 +1,46 @@ +name: CI Build + +on: + push: + pull_request: + +concurrency: + group: ci-build-${{ github.ref }} + cancel-in-progress: true + +jobs: + build: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Set up Java 8 + uses: actions/setup-java@v4 + with: + distribution: temurin + java-version: "8" + cache: maven + + - name: Restore JMeter cache + uses: actions/cache@v4 + with: + path: .jmeter + key: jmeter-${{ runner.os }}-${{ hashFiles('pom.xml', 'src/test/resources/jmeter/**') }} + restore-keys: | + jmeter-${{ runner.os }}- + + - name: Build and test + run: xvfb-run -a mvn -U --batch-mode clean install + + - name: Upload build artifacts + if: always() + uses: actions/upload-artifact@v4 + with: + name: ci-build-artifacts-${{ github.run_id }} + path: | + target/jmeter-bzm-hls-*.jar + target/jmeter-test + target/failsafe-reports + if-no-files-found: warn + retention-days: 30 diff --git a/.github/workflows/ci-jmeter-compatibility.yaml b/.github/workflows/ci-jmeter-compatibility.yaml new file mode 100644 index 0000000..dd7fac1 --- /dev/null +++ b/.github/workflows/ci-jmeter-compatibility.yaml @@ -0,0 +1,101 @@ +name: CI JMeter Compatibility + +on: + push: + branches: + - SETUP_PIPELINES + workflow_dispatch: + inputs: + run_cloud_test: + description: "Run BlazeMeter cloud Taurus test (requires BZ_TOKEN)" + required: false + default: true + type: boolean + +jobs: + jmeter_compatibility: + runs-on: ubuntu-latest + timeout-minutes: 120 + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Set up Java 8 + uses: actions/setup-java@v4 + with: + distribution: temurin + java-version: "8" + cache: maven + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install Taurus + run: | + python -m pip install --upgrade pip + # Install Taurus from pinned constraints to avoid upstream resolver drift. + python -m pip install -r .github/taurus-constraints.txt + python --version + python - <<'PY' + import importlib.metadata as metadata + for pkg in ("bzt", "urwid"): + print(f"{pkg}=={metadata.version(pkg)}") + PY + + - name: Restore JMeter cache + uses: actions/cache@v4 + with: + path: .jmeter + key: jmeter-${{ runner.os }}-${{ hashFiles('pom.xml', 'src/test/resources/jmeter/**') }} + restore-keys: | + jmeter-${{ runner.os }}- + + - name: Build project and jmeter-test bundle + run: xvfb-run -a mvn -U --batch-mode clean install + + - name: Run compatibility matrix on Java 8 + working-directory: target/jmeter-test + run: | + JMETER_VERSION=3.3 sh testJmeter.sh + JMETER_VERSION=4.0 sh testJmeter.sh + JMETER_VERSION=5.1 sh testJmeter.sh + JMETER_VERSION=5.1.1 sh testJmeter.sh + JMETER_VERSION=5.2.1 sh testJmeter.sh + JMETER_VERSION=5.3 sh testJmeter.sh + JMETER_VERSION=5.4.1 sh testJmeter.sh + JMETER_VERSION=5.5 sh testJmeter.sh + + - name: Set up Java 11 + uses: actions/setup-java@v4 + with: + distribution: temurin + java-version: "11" + cache: maven + + - name: Run Java 11 compatibility case + working-directory: target/jmeter-test + run: | + JMETER_VERSION=5.0 sh testJmeter.sh + + - name: Run BlazeMeter cloud test + if: ${{ inputs.run_cloud_test }} + working-directory: target/jmeter-test + env: + BZ_TOKEN: ${{ secrets.BZ_TOKEN }} + run: | + if [ -z "$BZ_TOKEN" ]; then + echo "BZ_TOKEN secret is required when run_cloud_test is enabled." + exit 1 + fi + bzt testJMeterBZ.yaml -o modules.cloud.token=${BZ_TOKEN} + + - name: Upload compatibility artifacts on failure + if: failure() + uses: actions/upload-artifact@v4 + with: + name: ci-jmeter-compat-failure-${{ github.run_id }} + path: target/jmeter-test + if-no-files-found: warn + retention-days: 1 diff --git a/.github/workflows/ci-master-slave.yaml b/.github/workflows/ci-master-slave.yaml new file mode 100644 index 0000000..0abb2af --- /dev/null +++ b/.github/workflows/ci-master-slave.yaml @@ -0,0 +1,45 @@ +name: CI Master Slave Test + +on: + workflow_dispatch: + push: + branches: + - SETUP_PIPELINES + +jobs: + master_slave_test: + runs-on: ubuntu-latest + timeout-minutes: 60 + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Set up Java 8 + uses: actions/setup-java@v4 + with: + distribution: temurin + java-version: "8" + cache: maven + + - name: Clean known corrupted Maven artifact + run: | + rm -f ~/.m2/repository/xml-apis/xmlParserAPIs/2.0.2/xmlParserAPIs-2.0.2.pom + + - name: Run MasterSlaveIT + env: + TESTCONTAINERS_RYUK_DISABLED: "true" + run: | + mvn -U --batch-mode clean install -DskipTests + mvn -U --batch-mode -Dtest=MasterSlaveIT test + + - name: Upload master-slave artifacts + if: always() + uses: actions/upload-artifact@v4 + with: + name: ci-master-slave-artifacts-${{ github.run_id }} + path: | + target/jmeter-bzm-hls-*.jar + target/jmeter-test + target/failsafe-reports + if-no-files-found: warn + retention-days: 30 diff --git a/.github/workflows/ci-release.yaml b/.github/workflows/ci-release.yaml new file mode 100644 index 0000000..a90cb64 --- /dev/null +++ b/.github/workflows/ci-release.yaml @@ -0,0 +1,65 @@ +name: CI Release + +on: + workflow_dispatch: + +permissions: + contents: write + +jobs: + release: + runs-on: ubuntu-latest + environment: release + timeout-minutes: 90 + steps: + - name: Checkout full history + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Ensure workflow runs on master + run: | + if [ "${GITHUB_REF_NAME}" != "master" ]; then + echo "This workflow must be run from master. Current ref: ${GITHUB_REF_NAME}" + exit 1 + fi + + - name: Set up Java 8 + uses: actions/setup-java@v4 + with: + distribution: temurin + java-version: "8" + cache: maven + + - name: Install VNC dependencies + run: | + sudo apt-get update + sudo apt-get install -y tightvncserver x11-utils + + - name: Wire release scripts to root paths + run: | + chmod +x pipeline/jmeter-plugins-build/scripts/*.sh + sudo ln -sf "${GITHUB_WORKSPACE}/pipeline/jmeter-plugins-build/scripts/release.sh" /release.sh + sudo ln -sf "${GITHUB_WORKSPACE}/pipeline/jmeter-plugins-build/scripts/set-git-credentials.sh" /set-git-credentials.sh + sudo ln -sf "${GITHUB_WORKSPACE}/pipeline/jmeter-plugins-build/scripts/execute-on-vnc.sh" /execute-on-vnc.sh + sudo chmod +x /release.sh /set-git-credentials.sh /execute-on-vnc.sh + + - name: Run release script + env: + SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }} + SSH_KNOWN_HOSTS: ${{ secrets.SSH_KNOWN_HOSTS }} + run: | + if [ -z "$SSH_PRIVATE_KEY" ] || [ -z "$SSH_KNOWN_HOSTS" ]; then + echo "SSH_PRIVATE_KEY and SSH_KNOWN_HOSTS secrets are required for release." + exit 1 + fi + /release.sh + + - name: Upload release artifacts + if: always() + uses: actions/upload-artifact@v4 + with: + name: ci-release-artifacts-${{ github.run_id }} + path: target/jmeter-bzm-hls-*.jar + if-no-files-found: warn + retention-days: 30 diff --git a/pom.xml b/pom.xml index ab7f5d9..4034ee5 100755 --- a/pom.xml +++ b/pom.xml @@ -15,10 +15,10 @@ - scm:git:git@gitlab.abstracta.us:BZ/jmeter-hls-plugin.git - scm:git:git@gitlab.abstracta.us:BZ/jmeter-hls-plugin.git + scm:git:git@github.com:Blazemeter/HLSPlugin.git + scm:git:git@github.com:Blazemeter/HLSPlugin.git - http://gitlab.abstracta.us/BZ/jmeter-hls-plugin + https://github.com/Blazemeter/HLSPlugin @@ -73,7 +73,7 @@ org.testcontainers testcontainers - 1.14.3 + 1.19.7 test diff --git a/src/test/java/com/blazemeter/jmeter/MasterSlaveIT.java b/src/test/java/com/blazemeter/jmeter/MasterSlaveIT.java index b01504c..d5df9a7 100644 --- a/src/test/java/com/blazemeter/jmeter/MasterSlaveIT.java +++ b/src/test/java/com/blazemeter/jmeter/MasterSlaveIT.java @@ -5,6 +5,7 @@ import java.io.File; import java.io.IOException; import java.time.Duration; +import java.util.Arrays; import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; @@ -24,6 +25,7 @@ public class MasterSlaveIT { private static final Logger LOG = LoggerFactory.getLogger(MasterSlaveIT.class); private static final long TIMEOUT_MILLI = 120000; private static final String JMETER_HOME_PATH = "/jmeter/apache-jmeter-5.1.1/bin"; + private static final String JMETER_TEST_LIB_PATH = "target/jmeter-test/lib"; private static final Network network = Network.newNetwork(); @Rule @@ -51,9 +53,9 @@ public class MasterSlaveIT { .withFileFromClasspath("Dockerfile", "master-slave/Dockerfile") .withFileFromClasspath("test.jmx", "master-slave/HLSSamplerSlaveRemoteTest.jmx") .withFileFromFile("jmeter-bzm-hls.jar", - new File("target/jmeter-test/lib/jmeter-bzm-hls.jar")) + getJarByPrefix("jmeter-bzm-hls-")) .withFileFromFile("hlsparserj.jar", - new File("target/jmeter-test/lib/hlsparserj.jar")) + getJarByPrefix("hlsparserj-")) .withDockerfilePath("Dockerfile")) .withLogConsumer(new Slf4jLogConsumer(LOG).withPrefix("MAIN")) .withNetwork(network) @@ -73,4 +75,15 @@ public void shouldRunHLSMasterSlaveTestWhenStartContainer() assertThat(execResult.getStdout()).contains("... end of run"); } + private static File getJarByPrefix(String prefix) { + File libDir = new File(JMETER_TEST_LIB_PATH); + File[] matches = libDir.listFiles((dir, name) -> name.startsWith(prefix) && name.endsWith(".jar")); + if (matches == null || matches.length == 0) { + throw new IllegalStateException("Could not find jar with prefix '" + prefix + "' in " + + libDir.getAbsolutePath()); + } + Arrays.sort(matches); + return matches[matches.length - 1]; + } + } diff --git a/src/test/resources/master-slave/Dockerfile b/src/test/resources/master-slave/Dockerfile index 830f5a6..f5e9c67 100644 --- a/src/test/resources/master-slave/Dockerfile +++ b/src/test/resources/master-slave/Dockerfile @@ -1,8 +1,7 @@ -FROM java:8 +FROM eclipse-temurin:8-jre -# Updating system & installing net-tools to have ifconfig command avaiable -# Due to issue non-zero code 100 (returned by apt-get update -y), this was the approach found to install net-tools. -RUN apt-get update -y || apt-get install -y net-tools +# Install tools required by the test image setup. +RUN apt-get update -y && apt-get install -y wget net-tools && rm -rf /var/lib/apt/lists/* ENV JMETER_VERSION 5.1.1 diff --git a/src/test/resources/master-slave/WiremockDockerfile b/src/test/resources/master-slave/WiremockDockerfile index c55ac9d..d575665 100644 --- a/src/test/resources/master-slave/WiremockDockerfile +++ b/src/test/resources/master-slave/WiremockDockerfile @@ -1,8 +1,11 @@ -FROM java:8 +FROM eclipse-temurin:8-jre ENV WIREMOCK_VERSION 2.26.3 -RUN mkdir -p /wiremock/mappings/ \ +RUN apt-get update -y \ + && apt-get install -y wget netcat-openbsd \ + && rm -rf /var/lib/apt/lists/* \ + && mkdir -p /wiremock/mappings/ \ && cd /wiremock \ && wget https://repo1.maven.org/maven2/com/github/tomakehurst/wiremock-standalone/$WIREMOCK_VERSION/wiremock-standalone-$WIREMOCK_VERSION.jar \ && cd /wiremock