generated from amazon-archives/__template_Apache-2.0
-
Notifications
You must be signed in to change notification settings - Fork 8
Feat network steps #173
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
Open
jaiszeen
wants to merge
24
commits into
aws-greengrass:dev_v1
Choose a base branch
from
jaiszeen:feat_network_steps
base: dev_v1
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Feat network steps #173
Changes from all commits
Commits
Show all changes
24 commits
Select commit
Hold shift + click to select a range
ed486dd
feat: comman-connectivity-steps
jaiszeen 2ba72d0
fix: pr comment
jaiszeen a243a74
feat: connectivitystep
jaiszeen eac15c6
fix: connectivitystep
jaiszeen eccbd3a
fix: pr comments
jaiszeen f39d33a
feat: comman-connectivity-steps
jaiszeen 434e077
fix: pr comment
jaiszeen 011b09a
feat: connectivitystep
jaiszeen f88cece
fix: connectivitystep
jaiszeen 7ccc866
fix: pr comments
jaiszeen fbd002d
Merge branch 'main' into feat_network_steps
jaiszeen b539e9e
fix: comments
jaiszeen 5b319ff
Merge branch 'feat_network_steps' of https://github.com/jaiszeen/aws-…
jaiszeen 12ea59f
fix: pr comments
jaiszeen 47ddba6
fix: comments
jaiszeen 43a1dfc
fix: comments
jaiszeen bdb94d6
fix: comments
jaiszeen bc552b6
fix: dependency
jaiszeen ba75c37
fix: dependency
jaiszeen 74f7203
fix: dependency
jaiszeen b00884a
fix: dependency
jaiszeen b5155b3
fix: comments
jaiszeen 7159dcc
fix: comments
jaiszeen 52a765c
fix: method documentation
Nelsonochoam File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
59 changes: 59 additions & 0 deletions
59
...ing-features-api/src/main/java/com/aws/greengrass/testing/features/ConnectivitySteps.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,59 @@ | ||
| /* | ||
| * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
| * SPDX-License-Identifier: Apache-2.0 | ||
| */ | ||
|
|
||
| package com.aws.greengrass.testing.features; | ||
|
|
||
| import com.aws.greengrass.testing.platform.Platform; | ||
| import io.cucumber.guice.ScenarioScoped; | ||
| import io.cucumber.java.After; | ||
| import io.cucumber.java.en.When; | ||
|
|
||
| import java.io.IOException; | ||
| import javax.inject.Inject; | ||
|
|
||
| @ScenarioScoped | ||
| public class ConnectivitySteps { | ||
| private final Platform platform; | ||
| private boolean offline = false; | ||
|
|
||
| @Inject | ||
| @SuppressWarnings("MissingJavadocMethod") | ||
| public ConnectivitySteps(Platform platform) { | ||
| this.platform = platform; | ||
| } | ||
|
|
||
| /** | ||
| * Blocks the traffic on ports 443, 8888, 8889 when the connectivity parameter is "offline" and | ||
| * re-enables traffic on the ports when it is "online". | ||
| * | ||
| * @param connectivity desired connectivity status ("offline", "online") | ||
| * @throws IOException {throws IOException} | ||
| * @throws InterruptedException {throws IInterruptedException} | ||
| * @throws UnsupportedOperationException {throws UnsupportedOperationException} | ||
| */ | ||
| @When("the device network connectivity is {word}") | ||
| public void setDeviceNetwork(final String connectivity) throws IOException, InterruptedException { | ||
| switch (connectivity.toLowerCase()) { | ||
| case "offline": | ||
| platform.getNetworkUtils().disconnectNetwork(); | ||
| break; | ||
| case "online": | ||
| platform.getNetworkUtils().recoverNetwork(); | ||
| break; | ||
| default: | ||
| throw new UnsupportedOperationException("Connectivity " + connectivity + " is not supported"); | ||
| } | ||
|
|
||
| offline = "offline".equalsIgnoreCase(connectivity); | ||
| } | ||
|
|
||
| @After | ||
| private void teardown() throws IOException, InterruptedException { | ||
| if (offline) { | ||
| platform.getNetworkUtils().recoverNetwork(); | ||
| } | ||
| } | ||
| } | ||
|
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
26 changes: 26 additions & 0 deletions
26
...-testing-platform-api/src/main/java/com/aws/greengrass/testing/platform/NetworkUtils.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| /* | ||
| * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
| * SPDX-License-Identifier: Apache-2.0 | ||
| */ | ||
|
|
||
| package com.aws.greengrass.testing.platform; | ||
|
|
||
| import java.io.IOException; | ||
| import java.io.UnsupportedEncodingException; | ||
| import java.util.ArrayList; | ||
| import java.util.List; | ||
|
|
||
| public abstract class NetworkUtils { | ||
| protected static final String[] MQTT_PORTS = {"8883", "443"}; | ||
| // 8888 and 8889 are used by the squid proxy which runs on a remote DUT | ||
| // and need to disable access to test offline proxy scenarios | ||
| protected static final String[] NETWORK_PORTS = {"443", "8888", "8889"}; | ||
| protected static final int[] GG_UPSTREAM_PORTS = {8883, 8443, 443}; | ||
| protected static final int SSH_PORT = 22; | ||
| protected final List<Integer> blockedPorts = new ArrayList<>(); | ||
|
|
||
| public abstract void disconnectNetwork() throws InterruptedException, IOException; | ||
|
|
||
| public abstract void recoverNetwork() throws InterruptedException, IOException; | ||
|
|
||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
136 changes: 136 additions & 0 deletions
136
...atform-api/src/main/java/com/aws/greengrass/testing/platform/linux/NetworkUtilsLinux.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,136 @@ | ||
| /* | ||
| * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
| * SPDX-License-Identifier: Apache-2.0 | ||
| */ | ||
|
|
||
| package com.aws.greengrass.testing.platform.linux; | ||
|
|
||
| import com.aws.greengrass.testing.platform.NetworkUtils; | ||
| import software.amazon.awssdk.utils.IoUtils; | ||
|
|
||
| import java.io.IOException; | ||
| import java.net.NetworkInterface; | ||
| import java.nio.charset.StandardCharsets; | ||
| import java.util.Collections; | ||
| import java.util.Enumeration; | ||
| import java.util.List; | ||
| import java.util.concurrent.TimeUnit; | ||
| import java.util.concurrent.atomic.AtomicBoolean; | ||
| import java.util.stream.Collectors; | ||
| import java.util.stream.Stream; | ||
|
|
||
|
|
||
| public class NetworkUtilsLinux extends NetworkUtils { | ||
| private static final String ENABLE_OPTION = "--insert"; | ||
| private static final String DISABLE_OPTION = "--delete"; | ||
| private static final String APPEND_OPTION = "-A"; | ||
| private static final String IPTABLE_COMMAND_BLOCK_INGRESS_STR = | ||
| "sudo iptables %s INPUT -p tcp --sport %s -j REJECT"; | ||
| private static final String IPTABLE_COMMAND_STR = "sudo iptables %s OUTPUT -p tcp --dport %s -j REJECT && " | ||
| + "sudo iptables %s INPUT -p tcp --sport %s -j REJECT"; | ||
| private static final String IPTABLES_DROP_DPORT_EXTERNAL_ONLY_COMMAND_STR = | ||
| "sudo iptables %s INPUT -p tcp -s localhost --dport %s -j ACCEPT && " | ||
| + | ||
| "sudo iptables %s INPUT -p tcp --dport %s -j DROP && " | ||
| + | ||
| "sudo iptables %s OUTPUT -p tcp -d localhost --dport %s -j ACCEPT && " | ||
| + | ||
| "sudo iptables %s OUTPUT -p tcp --dport %s -j DROP"; | ||
| private static final String IPTABLE_SAFELIST_COMMAND_STR | ||
| = "sudo iptables %s OUTPUT -p tcp -d %s --dport %d -j ACCEPT && " | ||
| + | ||
| "sudo iptables %s INPUT -p tcp -s %s --sport %d -j ACCEPT"; | ||
| private static final String GET_IPTABLES_RULES = "sudo iptables -S"; | ||
|
|
||
| // The string we are looking for to verify that there is an iptables rule to reject a port | ||
| // We only need to look for sport because sport only gets created if dport is successful | ||
| private static final String IPTABLES_RULE = "-m tcp --sport %s -j REJECT"; | ||
|
|
||
| private static final AtomicBoolean bandwidthSetup = new AtomicBoolean(false); | ||
|
|
||
|
|
||
| private void modifyMqttConnection(String action) throws IOException, InterruptedException { | ||
| for (String port : MQTT_PORTS) { | ||
| new ProcessBuilder().command( | ||
| "sh", "-c", String.format(IPTABLES_DROP_DPORT_EXTERNAL_ONLY_COMMAND_STR, | ||
| action, port, action, port, action, port, action, port) | ||
| ).start().waitFor(2, TimeUnit.SECONDS); | ||
| } | ||
| } | ||
|
|
||
| private void filterPortOnInterface(String iface, int port) throws IOException, InterruptedException { | ||
| // Filtering SSH traffic impacts test execution, so we explicitly disallow it | ||
| if (port == SSH_PORT) { | ||
| return; | ||
| } | ||
| List<String> filterSourcePortCommand = Stream.of("sudo", "tc", "filter", "add", "dev", | ||
| iface, "parent", "1:", "protocol", "ip", "prio", "1", "u32", "match", | ||
| "ip", "sport", Integer.toString(port), "0xffff", "flowid", "1:2").collect(Collectors.toList()); | ||
| executeCommand(filterSourcePortCommand); | ||
|
|
||
| List<String> filterDestPortCommand = Stream.of("sudo", "tc", "filter", "add", "dev", iface, | ||
| "parent", "1:", "protocol", "ip", "prio", "1", "u32", "match", | ||
| "ip", "dport", Integer.toString(port), "0xffff", "flowid", "1:2").collect(Collectors.toList()); | ||
| executeCommand(filterDestPortCommand); | ||
| } | ||
|
|
||
| private void deleteRootNetemQdiscOnInterface() throws InterruptedException, IOException { | ||
| Enumeration<NetworkInterface> nets = NetworkInterface.getNetworkInterfaces(); | ||
| for (NetworkInterface netint : Collections.list(nets)) { | ||
| if (netint.isPointToPoint() || netint.isLoopback()) { | ||
| continue; | ||
| } | ||
| executeCommand(Stream.of("sudo", "tc", "qdisc", "del", "dev", netint.getName(), "root") | ||
| .collect(Collectors.toList())); | ||
| } | ||
| } | ||
|
|
||
| private void createRootNetemQdiscOnInterface(String iface, int netemRateKbps) | ||
| throws InterruptedException, IOException { | ||
| // TODO: Add support for setting packet loss and delay | ||
| int netemDelayMs = 750; | ||
| List<String> addQdiscCommand = Stream.of("sudo", "tc", "qdisc", "add", "dev", iface, "root", "handle", | ||
| "1:", "prio", "bands", "2", "priomap", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", | ||
| "0", "0", "0", "0", "0").collect(Collectors.toList()); | ||
| executeCommand(addQdiscCommand); | ||
|
|
||
| List<String> netemCommand = | ||
| Stream.of("sudo", "tc", "qdisc", "add", "dev", iface, "parent", "1:2", "netem", "delay", | ||
| String.format("%dms", netemDelayMs), "rate", String.format("%dkbit", netemRateKbps)) | ||
| .collect(Collectors.toList()); | ||
| executeCommand(netemCommand); | ||
| } | ||
|
|
||
| private String executeCommand(List<String> command) throws IOException, InterruptedException { | ||
| Process proc = new ProcessBuilder().command(command).start(); | ||
| proc.waitFor(2, TimeUnit.SECONDS); | ||
| if (proc.exitValue() != 0) { | ||
| throw new IOException("CLI command " + command + " failed with error " | ||
| + new String(IoUtils.toByteArray(proc.getErrorStream()), StandardCharsets.UTF_8)); | ||
| } | ||
| return new String(IoUtils.toByteArray(proc.getInputStream()), StandardCharsets.UTF_8); | ||
| } | ||
|
|
||
| @Override | ||
| public void disconnectNetwork() throws InterruptedException, IOException { | ||
| interfacepolicy(IPTABLE_COMMAND_STR, ENABLE_OPTION, "connection-loss", NETWORK_PORTS); | ||
| } | ||
|
|
||
| @Override | ||
| public void recoverNetwork() throws InterruptedException, IOException { | ||
| interfacepolicy(IPTABLE_COMMAND_STR, DISABLE_OPTION, "connection-recover", NETWORK_PORTS); | ||
|
|
||
| if (bandwidthSetup.get()) { | ||
Nelsonochoam marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| deleteRootNetemQdiscOnInterface(); | ||
| bandwidthSetup.set(false); | ||
| } | ||
| } | ||
|
|
||
| private void interfacepolicy(String iptableCommandString, String option, String eventName, String... ports) | ||
| throws InterruptedException, IOException { | ||
| for (String port : ports) { | ||
| new ProcessBuilder().command("sh", "-c", String.format(iptableCommandString, option, port, option, port)) | ||
| .start().waitFor(2, TimeUnit.SECONDS); | ||
| } | ||
| } | ||
| } | ||
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.