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

Scenario builder for unit tests #112

Merged
merged 1 commit into from
Aug 12, 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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
### Added
- Support for bootstrapper TRC metadata. [#110](https://github.com/scionproto-contrib/jpan/pull/110)
- Added `copy(...)` method for paths. [#111](https://github.com/scionproto-contrib/jpan/pull/111)
- Added Scenario builder for unit tests. [#112](https://github.com/scionproto-contrib/jpan/pull/112)

### Changed
- Clean up TODO and deprecation info. [#100](https://github.com/scionproto-contrib/jpan/pull/100)
Expand Down
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -330,12 +330,12 @@ attempt to get network information in the following order until it succeeds:
The reason that the daemon is checked last is that it has a default setting (`localhost:30255`)
while the other options are skipped if no property or environment variable is defined.

| Option | Java property | Environment variable | Default value |
|-------------------------------------|----------------------------------|-------------------------------|-----------------|
| Daemon port | `org.scion.daemon.port` | `SCION_DAEMON` | localhost:30255 |
| Bootstrap topology file path | `org.scion.bootstrap.topoFile` | `SCION_BOOTSTRAP_TOPO_FILE` | |
| Bootstrap server host | `org.scion.bootstrap.host` | `SCION_BOOTSTRAP_HOST` | |
| Bootstrap DNS NAPTR entry host name | `org.scion.bootstrap.naptr.name` | `SCION_BOOTSTRAP_NAPTR_NAME` | |
| Option | Java property | Environment variable | Default value |
|-------------------------------------|-------------------------------------|-------------------------------|-----------------|
| Daemon port | `org.scion.daemon.port` | `SCION_DAEMON` | localhost:30255 |
| Bootstrap topology file path | `org.scion.bootstrap.topoFile` | `SCION_BOOTSTRAP_TOPO_FILE` | |
| Bootstrap server host | `org.scion.bootstrap.host` | `SCION_BOOTSTRAP_HOST` | |
| Bootstrap DNS NAPTR entry host name | `org.scion.bootstrap.naptr.name` | `SCION_BOOTSTRAP_NAPTR_NAME` | |
| Bootstrap DNS NAPTR entry host name | `org.scion.test.useOsSearchDomains` | `SCION_USE_OS_SEARCH_DOMAINS` | true |

### DNS
Expand Down
9 changes: 6 additions & 3 deletions src/main/java/org/scion/jpan/Constants.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,16 +27,19 @@ public final class Constants {

/** Address of bootstrap server (http), e.g. 192.168.42.42 */
public static final String PROPERTY_BOOTSTRAP_HOST = "org.scion.bootstrap.host";

/** Address of bootstrap server (http), e.g. 192.168.42.42 */
public static final String ENV_BOOTSTRAP_HOST = "SCION_BOOTSTRAP_HOST";

/** Host name of DNS entry with NAPTR record for bootstrap service. */
public static final String PROPERTY_BOOTSTRAP_NAPTR_NAME = "org.scion.bootstrap.naptr.name";

/** Host name of DNS entry with NAPTR record for bootstrap service. */
public static final String ENV_BOOTSTRAP_NAPTR_NAME = "SCION_BOOTSTRAP_NAPTR_NAME";

/** path/file name for topology file. */
public static final String PROPERTY_BOOTSTRAP_TOPO_FILE = "org.scion.bootstrap.topoFile";

/** path/file name for topology file. */
public static final String ENV_BOOTSTRAP_TOPO_FILE = "SCION_BOOTSTRAP_TOPO_FILE";

Expand All @@ -62,12 +65,12 @@ public final class Constants {
public static final int DEFAULT_PATH_EXPIRY_MARGIN = 10;

/**
* Disable usage of OS search domains for DNS lookup, e.g from /etc/resolv.conf. This needs to be
* Disable usage of OS search domains for DNS lookup, e.g. from /etc/resolv.conf. This needs to be
* disabled for JUnit testing.
*/
public static final String PROPERTY_USE_OS_SEARCH_DOMAINS = "SCION_USE_OS_SEARCH_DOMAINS";
public static final String PROPERTY_USE_OS_SEARCH_DOMAINS = "org.scion.test.useOsSearchDomains";

public static final String ENV_USE_OS_SEARCH_DOMAINS = "org.scion.test.useOsSearchDomains";
public static final String ENV_USE_OS_SEARCH_DOMAINS = "SCION_USE_OS_SEARCH_DOMAINS";
public static final boolean DEFAULT_USE_OS_SEARCH_DOMAINS = true;

/**
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/org/scion/jpan/ScionService.java
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ protected ScionService(String addressOrHost, Mode mode) {
}
String csHost = bootstrapper.getLocalTopology().getControlServerAddress();
LOG.info("Bootstrapping with control service: {}", csHost);
localIsdAs.set(bootstrapper.getLocalTopology().getLocalIsdAs());
localIsdAs.set(bootstrapper.getLocalTopology().getIsdAs());
// TODO InsecureChannelCredentials: Implement authentication!
channel = Grpc.newChannelBuilder(csHost, InsecureChannelCredentials.create()).build();
daemonStub = null;
Expand Down
8 changes: 8 additions & 0 deletions src/main/java/org/scion/jpan/ScionUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -203,5 +203,13 @@ static InetSocketAddress parseInetSocketAddress(String addrStr) {
}
}

public static boolean isWildcard(long isdAs) {
return isdAs == toWildcard(isdAs);
}

public static long toWildcard(long isdAs) {
return (isdAs >>> 48) << 48;
}

private ScionUtil() {}
}
66 changes: 56 additions & 10 deletions src/main/java/org/scion/jpan/internal/LocalTopology.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import org.scion.jpan.ScionRuntimeException;
Expand Down Expand Up @@ -51,11 +52,11 @@ public String getControlServerAddress() {
return controlServices.get(0).ipString;
}

public boolean isLocalAsCore() {
public boolean isCoreAs() {
return isCoreAs;
}

public long getLocalIsdAs() {
public long getIsdAs() {
return ScionUtil.parseIA(localIsdAs);
}

Expand All @@ -78,7 +79,7 @@ public List<String> getBorderRouterAddresses() {
return result;
}

public int getLocalMtu() {
public int getMtu() {
return this.localMtu;
}

Expand All @@ -101,9 +102,12 @@ private void parseTopologyFile(String topologyFile) {
JsonElement local =
underlay.has(("local")) ? underlay.get(("local")) : underlay.get(("public"));
JsonElement remote = underlay.get(("remote"));
long isdAs = ScionUtil.parseIA(ife.get("isd_as").getAsString());
int mtu = ife.get("mtu").getAsInt();
String linkTo = ife.get("link_to").getAsString();
interfaces.add(
new BorderRouterInterface(
ifEntry.getKey(), local.getAsString(), remote.getAsString()));
ifEntry.getKey(), local.getAsString(), remote.getAsString(), isdAs, mtu, linkTo));
}
borderRouters.add(new BorderRouter(e.getKey(), addr, interfaces));
}
Expand Down Expand Up @@ -142,34 +146,76 @@ public String toString() {
}

public List<ServiceNode> getControlServices() {
return controlServices;
return Collections.unmodifiableList(controlServices);
}

private static class BorderRouter {
public List<BorderRouter> getBorderRouters() {
return Collections.unmodifiableList(borderRouters);
}

public static class BorderRouter {
private final String name;
private final String internalAddress;
private final List<BorderRouterInterface> interfaces;

public BorderRouter(String name, String addr, List<BorderRouterInterface> interfaces) {
BorderRouter(String name, String addr, List<BorderRouterInterface> interfaces) {
this.name = name;
this.internalAddress = addr;
this.interfaces = interfaces;
}

public Iterable<BorderRouterInterface> getInterfaces() {
return interfaces;
}
}

private static class BorderRouterInterface {
public static class BorderRouterInterface {
public static final String PARENT = "parent";
public static final String CHILD = "child";
public static final String CORE = "core";
final int id;
final String publicUnderlay;
final String remoteUnderlay;
final long isdAs;
final int mtu;
final String linkTo;

public BorderRouterInterface(String id, String publicU, String remoteU) {
BorderRouterInterface(
String id, String publicU, String remoteU, long isdAs, int mtu, String linkTo) {
this.id = Integer.parseInt(id);
this.publicUnderlay = publicU;
this.remoteUnderlay = remoteU;
this.isdAs = isdAs;
this.mtu = mtu;
this.linkTo = linkTo;
}

public long getIsdAs() {
return isdAs;
}

public int getMtu() {
return mtu;
}

public int getId() {
return id;
}

public String getLinkTo() {
return linkTo;
}

public String getRemoteUnderlay() {
return remoteUnderlay;
}

public String getPublicUnderlay() {
return publicUnderlay;
}
}

static class ServiceNode {
public static class ServiceNode {
final String name;
final String ipString;

Expand Down
8 changes: 8 additions & 0 deletions src/main/java/org/scion/jpan/internal/MultiMap.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,12 @@ public boolean isEmpty() {
public void clear() {
map.clear();
}

public List<V> values() {
ArrayList<V> values = new ArrayList<>(map.size());
for (Map.Entry<K, ArrayList<V>> e : map.entrySet()) {
values.addAll(e.getValue());
}
return values;
}
}
20 changes: 7 additions & 13 deletions src/main/java/org/scion/jpan/internal/ScionBootstrapper.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,22 +37,21 @@
public class ScionBootstrapper {

private static final Logger LOG = LoggerFactory.getLogger(ScionBootstrapper.class.getName());
private static final String BASE_URL = "";
private static final String TOPOLOGY_ENDPOINT = "topology";
private static final Duration httpRequestTimeout = Duration.of(2, ChronoUnit.SECONDS);
private final String topologyResource;
private final LocalTopology topology;
private final LocalTopology localAS;
private final GlobalTopology world;

protected ScionBootstrapper(String topologyServiceAddress) {
this.topologyResource = topologyServiceAddress;
this.topology = initLocal();
this.localAS = initLocal();
this.world = initGlobal();
}

protected ScionBootstrapper(java.nio.file.Path file) {
this.topologyResource = file.toString();
this.topology = this.init(file);
this.localAS = this.init(file);
this.world = GlobalTopology.createEmpty();
}

Expand All @@ -75,7 +74,7 @@ public static synchronized ScionBootstrapper createViaTopoFile(java.nio.file.Pat
}

public LocalTopology getLocalTopology() {
return topology;
return localAS;
}

public GlobalTopology getGlobalTopology() {
Expand All @@ -95,12 +94,7 @@ private static String bootstrapViaDNS(String hostName) {
}

private LocalTopology initLocal() {
LocalTopology topo = LocalTopology.create(fetchFile(TOPOLOGY_ENDPOINT));
if (topo.getControlServices().isEmpty()) {
throw new ScionRuntimeException(
"No control servers found in topology provided by " + topologyResource);
}
return topo;
return LocalTopology.create(fetchFile(TOPOLOGY_ENDPOINT));
}

private GlobalTopology initGlobal() {
Expand Down Expand Up @@ -129,7 +123,7 @@ private LocalTopology init(java.nio.file.Path file) {
}
LocalTopology topo = LocalTopology.create(contentBuilder.toString());
if (topo.getControlServices().isEmpty()) {
throw new ScionRuntimeException("No control service found in topology filet: " + file);
throw new ScionRuntimeException("No control service found in topology file: " + file);
}
return topo;
}
Expand All @@ -144,7 +138,7 @@ public void refreshTopology() {
public String fetchFile(String resource) {
try {
LOG.info("Fetching resource from bootstrap server: {} {}", topologyResource, resource);
URL url = new URL("http://" + topologyResource + "/" + BASE_URL + resource);
URL url = new URL("http://" + topologyResource + "/" + resource);
return fetchFile(url);
} catch (IOException e) {
throw new ScionRuntimeException(
Expand Down
8 changes: 4 additions & 4 deletions src/main/java/org/scion/jpan/internal/Segments.java
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ public static List<Daemon.Path> getPaths(
if (srcIsdAs == dstIsdAs) {
// case A: same AS, return empty path
Daemon.Path.Builder path = Daemon.Path.newBuilder();
path.setMtu(localAS.getLocalMtu());
path.setMtu(localAS.getMtu());
path.setExpiration(Timestamp.newBuilder().setSeconds(Instant.now().getEpochSecond()).build());
return Collections.singletonList(path.build());
}
Expand All @@ -189,7 +189,7 @@ public static List<Daemon.Path> getPaths(
long to = dstIsdAs;
List<List<Seg.PathSegment>> segments = new ArrayList<>();
// First, if necessary, try to get UP segments
if (!localAS.isLocalAsCore()) {
if (!localAS.isCoreAs()) {
// get UP segments
// TODO find out if dstIsAs is core and directly ask for it.
List<Seg.PathSegment> segmentsUp = getSegments(segmentStub, srcIsdAs, srcWildcard);
Expand Down Expand Up @@ -421,7 +421,7 @@ private static Daemon.Path buildPath(LocalTopology localAS, Seg.PathSegment... s

// info fields
boolean[] reversed = new boolean[segments.length];
long startIA = localAS.getLocalIsdAs();
long startIA = localAS.getIsdAs();
final ByteUtil.MutLong endingIA = new ByteUtil.MutLong(-1);
for (int i = 0; i < infos.length; i++) {
reversed[i] = isReversed(segments[i], startIA, endingIA);
Expand All @@ -430,7 +430,7 @@ private static Daemon.Path buildPath(LocalTopology localAS, Seg.PathSegment... s
}

// hop fields
path.setMtu(localAS.getLocalMtu());
path.setMtu(localAS.getMtu());
for (int i = 0; i < segments.length; i++) {
// bytePosSegID: 6 = 4 bytes path head + 2 byte flag in first info field
writeHopFields(path, raw, 6 + i * 8, segments[i], reversed[i], infos[i]);
Expand Down
4 changes: 2 additions & 2 deletions src/test/java/org/scion/jpan/ProtobufPathDemo.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,12 @@ public class ProtobufPathDemo {

public static void main(String[] args) {
try (Scion.CloseableService daemon =
Scion.newServiceWithDaemon(DemoConstants.daemon110_minimal)) {
Scion.newServiceWithDaemon(DemoConstants.daemon1111_minimal)) {
ProtobufPathDemo demo = new ProtobufPathDemo(daemon);
demo.testAsInfo();
demo.testInterfaces();
demo.testServices();
demo.testPathsDaemon(DemoConstants.ia110, DemoConstants.ia211);
demo.testPathsDaemon(DemoConstants.ia1111, DemoConstants.ia1112);
// demo.testPathsControlService(srcIA, dstIA);
} catch (IOException e) {
throw new RuntimeException(e);
Expand Down
4 changes: 0 additions & 4 deletions src/test/java/org/scion/jpan/ProtobufSegmentDemo.java
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,6 @@ public static void main(String[] args) throws ScionException {
// demo.getSegments(toWildcard(ia120), toWildcard(ia210));
}

private static long toWildcard(long ia) {
return (ia >>> 48) << 48;
}

public ProtobufSegmentDemo(String csAddress) {
channel = Grpc.newChannelBuilder(csAddress, InsecureChannelCredentials.create()).build();
segmentStub = SegmentLookupServiceGrpc.newBlockingStub(channel);
Expand Down
4 changes: 2 additions & 2 deletions src/test/java/org/scion/jpan/ScionBootstrapperTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ void testTiny110() {
ScionBootstrapper sb = ScionBootstrapper.createViaTopoFile(topoFile);
LocalTopology topo = sb.getLocalTopology();

assertEquals(ScionUtil.parseIA("1-ff00:0:110"), topo.getLocalIsdAs());
assertEquals(ScionUtil.parseIA("1-ff00:0:110"), topo.getIsdAs());
assertEquals("127.0.0.11:31000", topo.getControlServerAddress());
assertTrue(topo.isLocalAsCore());
assertTrue(topo.isCoreAs());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,11 @@ void test() {
PingPongChannelHelper.Client clientFn = this::client;
PingPongChannelHelper pph = new PingPongChannelHelper(1, 2, 10);
pph.runPingPong(serverFn, clientFn, false);
assertEquals(2 * 10, MockNetwork.getForwardCount(0));
// TODO: This sometimes reports 22 i.o. 20.
assertEquals(
2 * 10,
MockNetwork.getForwardCount(0),
"Actual: " + MockNetwork.getForwardCount(0) + "/" + MockNetwork.getForwardCount(1));
assertEquals(2 * 10, MockNetwork.getForwardCount(1));
assertEquals(2 * 2 * 10, MockNetwork.getAndResetForwardCount());
}
Expand Down
2 changes: 0 additions & 2 deletions src/test/java/org/scion/jpan/api/ScionTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,6 @@ void newServiceWithDNS() throws IOException {
assertNotNull(paths);
assertFalse(paths.isEmpty());
assertEquals(1, MockNetwork.getTopoServer().getAndResetCallCount());
assertEquals(1, MockNetwork.getControlServer().getAndResetCallCount());
assertNotEquals(Scion.defaultService(), ss);
} finally {
MockNetwork.stopTiny();
Expand All @@ -319,7 +318,6 @@ void newServiceWithBootstrapServer() throws IOException {
assertNotNull(paths);
assertFalse(paths.isEmpty());
assertEquals(1, MockNetwork.getTopoServer().getAndResetCallCount());
assertEquals(1, MockNetwork.getControlServer().getAndResetCallCount());
// No DNS, no daemon, no ENV variables -> fail.
assertThrows(ScionRuntimeException.class, Scion::defaultService);
} finally {
Expand Down
Loading
Loading