/*- * -\-\- * Helios Tools * -- * Copyright (C) 2016 - 2017 Spotify AB * -- * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * -/-/- */ package com.spotify.helios.cli.command; import static com.spotify.helios.common.descriptors.PortMapping.TCP; import static com.spotify.helios.common.descriptors.PortMapping.UDP; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.equalTo; import com.google.common.collect.ImmutableList; import com.spotify.helios.cli.command.PortMappingParser.PortMappingWithName; import com.spotify.helios.common.descriptors.PortMapping; import java.util.HashMap; import java.util.List; import java.util.Map; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; public class PortMappingParserTest { @Rule public ExpectedException expectedException = ExpectedException.none(); private static final List<TestData> GOOD_SPECS = ImmutableList.of( TestData.of("http=8080:80", "http", PortMapping.of(8080, 80, TCP)), TestData.of("foo=4711:80/tcp", "foo", PortMapping.of(4711, 80, TCP)), TestData.of("dns=53:53/udp", "dns", PortMapping.of(53, 53, UDP)), TestData.of("bar=4711", "bar", PortMapping.of(4711, null, TCP)), TestData.of("smtp=0.0.0.0:53:53/udp", "smtp", PortMapping.builder() .ip("0.0.0.0") .internalPort(53) .externalPort(53) .protocol(UDP) .build()), TestData.of("mail=127.0.0.1:23:23/tcp", "mail", PortMapping.builder() .ip("127.0.0.1") .internalPort(23) .externalPort(23) .protocol(TCP) .build()), TestData.of("qux=10.99.0.1:1001:1002", "qux", PortMapping.builder() .ip("10.99.0.1") .internalPort(1001) .externalPort(1002) .protocol(TCP) .build()) ); private static final List<TestData> BAD_SPECS = ImmutableList.of( TestData.partial("smtp=localhost:53:53/udp"), TestData.partial("http8080:80"), TestData.partial("foo=80:4711:80/tcp"), TestData.partial("=53:53/udp"), TestData.partial("foo") ); @Test public void testParsePortMappingGoodSpecs() throws Exception { for (final TestData d : GOOD_SPECS) { final PortMappingWithName mappingWithName = PortMappingParser.parsePortMapping(d.getSpec()); final PortMapping portMapping = mappingWithName.portMapping(); assertThat(mappingWithName.name(), equalTo(d.getName())); assertThat(portMapping.getInternalPort(), equalTo(d.getPortMapping().getInternalPort())); assertThat(portMapping.getExternalPort(), equalTo(d.getPortMapping().getExternalPort())); assertThat(portMapping.getProtocol(), equalTo(d.getPortMapping().getProtocol())); } } @Test public void testParsePortMappingBadSpecs() throws Exception { for (final TestData d : BAD_SPECS) { expectedException.expect(IllegalArgumentException.class); expectedException.expectMessage("Bad port mapping: " + d.getSpec()); PortMappingParser.parsePortMapping(d.getSpec()); } } @Test public void testParsePortMappingBadIp() throws Exception { expectedException.expect(IllegalArgumentException.class); expectedException.expectMessage("999.999.999.999 is not a valid IP address."); final TestData d = TestData.partial("mail=999.999.999.999:23:23/tcp"); PortMappingParser.parsePortMapping(d.getSpec()); } @Test public void testParsePortMappings() throws Exception { final Map<String, PortMapping> mappings = PortMappingParser.parsePortMappings(testDataToSpecs(GOOD_SPECS)); final Map<String, PortMapping> expectedMappings = new HashMap<>(); for (final TestData d : GOOD_SPECS) { expectedMappings.put(d.getName(), d.getPortMapping()); } assertThat(mappings, equalTo(expectedMappings)); } @Test public void testParsePortMappingsDuplicateName() throws Exception { final ImmutableList<TestData> specs = ImmutableList.<TestData>builder() .addAll(GOOD_SPECS) .add(GOOD_SPECS.get(0)) .build(); expectedException.expect(IllegalArgumentException.class); expectedException.expectMessage("Duplicate port mapping name: " + GOOD_SPECS.get(0).getName()); PortMappingParser.parsePortMappings(testDataToSpecs(specs)); } private List<String> testDataToSpecs(final List<TestData> testData) { final ImmutableList.Builder<String> specs = ImmutableList.builder(); for (final TestData d : testData) { specs.add(d.getSpec()); } return specs.build(); } private static class TestData { private final String spec; private final String name; private final PortMapping portMapping; private TestData(final String spec, final String name, final PortMapping portMapping) { this.spec = spec; this.name = name; this.portMapping = portMapping; } static TestData partial(final String spec) { return new TestData(spec, null, null); } public static TestData of(final String spec, final String name, final PortMapping portMapping) { return new TestData(spec, name, portMapping); } String getSpec() { return spec; } String getName() { return name; } PortMapping getPortMapping() { return portMapping; } } }