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

Add end-to-end testing for the dump command #646

Merged
merged 18 commits into from
Dec 22, 2023
Merged
11 changes: 11 additions & 0 deletions incubator/command-dump/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
The `dump` command creates a `pcap` file that can be opened by Wireshark using the `zilla.lua` dissector plugin.

`WiresharkIT` is an integration test that tests the `zilla.lua` dissector by running `tshark` in a docker container. If it doesn't find the image, it builds it on-the-fly, but the process is faster if the `tshark` image is pre-built.

This is the command to build a multi-arch `tshark` image and push it to a docker repository:

```bash
cd <zilla-source>/incubator/command-dump/src/test/resources/io/aklivity/zilla/runtime/command/dump/internal/airline
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we need to have the Dockerfile in the test jar?
If not we can move this to src/test/docker instead so the instructions are a bit simpler.

Copy link
Contributor Author

@attilakreiner attilakreiner Dec 21, 2023

Choose a reason for hiding this comment

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

Yes, we need it. The setUp method here is implemented the way that it tries to find/pull the image first and if doesn't find it, then builds it on-the-fly.

ImageFromDockerfile image = new ImageFromDockerfile().withDockerfile(resourceToPath("Dockerfile"));

docker buildx create --name container --driver=docker-container
docker buildx build --tag <repository>/tshark:<version> --platform linux/arm64/v8,linux/amd64 --builder container --push .
```
40 changes: 38 additions & 2 deletions incubator/command-dump/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,47 @@
<version>${project.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>io.aklivity.zilla</groupId>
<artifactId>binding-proxy.spec</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.aklivity.zilla</groupId>
<artifactId>binding-http.spec</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>testcontainers</artifactId>
<version>1.19.3</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>junit-jupiter</artifactId>
<version>1.19.3</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.36</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.7.36</version>
<scope>test</scope>
</dependency>
</dependencies>

<build>
Expand All @@ -67,8 +103,8 @@
<artifactId>license-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>src/test/resources/io/aklivity/zilla/runtime/command/dump/internal/*</exclude>
<exclude>src/test/resources/io/aklivity/zilla/runtime/command/dump/internal/engine/*</exclude>
<exclude>src/test/resources/io/aklivity/zilla/runtime/command/dump/internal/airline/*</exclude>
<exclude>src/test/resources/io/aklivity/zilla/runtime/command/dump/internal/airline/engine/*</exclude>
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we scope the files a little more tightly so that new resources get caught automatically?
For example src/test/resources/**/*.pcap etc.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

fixed, pls chk

</excludes>
</configuration>
</plugin>
Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
/*
* Copyright 2021-2023 Aklivity Inc
*
* Licensed under the Aklivity Community License (the "License"); you may not use
* this file except in compliance with the License. You may obtain a copy of the
* License at
*
* https://www.aklivity.io/aklivity-community-license/
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*/
package io.aklivity.zilla.runtime.command.dump.internal.airline;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;
import static org.junit.jupiter.api.TestInstance.Lifecycle.PER_CLASS;

import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;

import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInstance;
import org.testcontainers.containers.Container;
import org.testcontainers.containers.ContainerFetchException;
import org.testcontainers.containers.GenericContainer;
import org.testcontainers.containers.wait.strategy.Wait;
import org.testcontainers.containers.wait.strategy.WaitStrategy;
import org.testcontainers.images.builder.ImageFromDockerfile;
import org.testcontainers.images.builder.Transferable;
import org.testcontainers.utility.DockerImageName;

@TestInstance(PER_CLASS)
public class WiresharkIT
{
private static final String TSHARK_DOCKER_IMAGE = "kreinerattila/tshark:4.2.0";
private static final String COMMAND = "sleep infinity";
private static final WaitStrategy WAIT_STRATEGY = Wait.forSuccessfulCommand("echo 42");

private GenericContainer<?> tshark;

@BeforeAll
public void setUp() throws IOException
{
try
{
System.out.printf("Starting the container using image %s...%n", TSHARK_DOCKER_IMAGE);
DockerImageName image = DockerImageName.parse(TSHARK_DOCKER_IMAGE);
tshark = new GenericContainer<>(image)
.withCommand(COMMAND)
.waitingFor(WAIT_STRATEGY);
tshark.start();
}
catch (ContainerFetchException ex)
{
System.out.printf("Image %s was not found, building it now...%n", TSHARK_DOCKER_IMAGE);
ImageFromDockerfile image = new ImageFromDockerfile().withDockerfile(resourceToPath("Dockerfile"));
tshark = new GenericContainer<>(image)
.withCommand(COMMAND)
.waitingFor(WAIT_STRATEGY);
tshark.start();
}
assert tshark.isRunning();
System.out.printf("Container %s (%s) is running!%n", tshark.getContainerName(), tshark.getContainerId());
copyResource("zilla.lua", tshark, "/home/tshark/.local/lib/wireshark/plugins/zilla.lua");
}

@AfterAll
public void close()
{
tshark.close();
}

@Test
public void shouldMatchExpectedOutput() throws Exception
{
// GIVEN
String pcapFileName = "expected_dump.pcap";
String containerPath = String.format("/opt/%s", pcapFileName);
copyResource(pcapFileName, tshark, containerPath);
String expectedText = Files.readString(resourceToPath("expected_dump.txt"));

// WHEN
String protocols = "zilla,http,http2";
Container.ExecResult result = tshark.execInContainer("tshark", "-O", protocols, "-r", containerPath);

// THEN
assertThat(result.getExitCode(), equalTo(0));
assertThat(result.getStdout(), equalTo(expectedText));
}

@Test
public void shouldMatchExpectedFilteredOutput() throws Exception
{
// GIVEN
String pcapFileName = "expected_filtered_dump.pcap";
String containerPath = String.format("/opt/%s", pcapFileName);
copyResource(pcapFileName, tshark, containerPath);
String expectedText = Files.readString(resourceToPath("expected_filtered_dump.txt"));

// WHEN
Container.ExecResult result = tshark.execInContainer("tshark", "-O", "zilla", "-r", containerPath);

// THEN
assertThat(result.getExitCode(), equalTo(0));
assertThat(result.getStdout(), equalTo(expectedText));
}

private static Path resourceToPath(
String name)
{
URL resource = WiresharkIT.class.getResource(name);
assert resource != null;
return Path.of(URI.create(resource.toString()));
}

private static void copyResource(
String resourceName,
GenericContainer<?> container,
String containerPath) throws IOException
{
assert container.isRunning();
try (InputStream is = WiresharkIT.class.getResourceAsStream(resourceName))
{
assert is != null;
container.copyFileToContainer(Transferable.of(is.readAllBytes()), containerPath);
}
}
}
Loading