package com.hubspot.baragon.service; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashSet; import java.util.Set; import com.google.common.base.Optional; import com.google.common.base.Throwables; import com.google.common.collect.ImmutableList; import com.hubspot.baragon.BaragonServiceTestModule; import com.hubspot.baragon.data.BaragonLoadBalancerDatastore; import com.hubspot.baragon.exceptions.InvalidRequestActionException; import com.hubspot.baragon.exceptions.InvalidUpstreamsException; import com.hubspot.baragon.exceptions.RequestAlreadyEnqueuedException; import com.hubspot.baragon.models.BaragonAgentMetadata; import com.hubspot.baragon.models.BaragonRequest; import com.hubspot.baragon.models.BaragonRequestState; import com.hubspot.baragon.models.BaragonResponse; import com.hubspot.baragon.models.BaragonService; import com.hubspot.baragon.models.UpstreamInfo; import com.hubspot.baragon.service.managers.RequestManager; import com.hubspot.baragon.service.worker.BaragonRequestWorker; import org.jukito.JukitoModule; import org.jukito.JukitoRunner; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; @RunWith(JukitoRunner.class) public class RequestTest { private static final Logger LOG = LoggerFactory.getLogger(RequestTest.class); public static final String REAL_LB_GROUP = "real"; public static final String FAKE_LB_GROUP = "fake"; public static class Module extends JukitoModule { @Override protected void configureTest() { install(new BaragonServiceTestModule()); } } @Before public void setupLbGroups(BaragonLoadBalancerTestDatastore loadBalancerDatastore) { loadBalancerDatastore.setLoadBalancerGroupsOverride(Optional.of(Collections.singleton(REAL_LB_GROUP))); BaragonAgentMetadata agent1 = BaragonAgentMetadata.fromString("http://127.0.0.1:8080/baragon-agent/v2"); Collection<BaragonAgentMetadata> agents = new ArrayList<>(); agents.add(agent1); loadBalancerDatastore.setLoadBalancerAgentsOverride(Optional.of(agents)); } @After public void clearBasePaths(BaragonLoadBalancerDatastore loadBalancerDatastore) { LOG.debug("Clearing base paths..."); for (String loadBalancerGroup : loadBalancerDatastore.getLoadBalancerGroupNames()) { for (String basePath : loadBalancerDatastore.getBasePaths(loadBalancerGroup)) { LOG.debug(String.format(" Clearing %s on %s", basePath, loadBalancerGroup)); loadBalancerDatastore.clearBasePath(loadBalancerGroup, basePath); } } } private Optional<BaragonResponse> assertResponseStateExists(RequestManager requestManager, String requestId, BaragonRequestState expected) { final Optional<BaragonResponse> maybeResponse = requestManager.getResponse(requestId); assertTrue(String.format("Response for request %s exists", requestId), maybeResponse.isPresent()); assertEquals(expected, maybeResponse.get().getLoadBalancerState()); return maybeResponse; } private Optional<BaragonResponse> assertResponseStateAbsent(RequestManager requestManager, String requestId) { final Optional<BaragonResponse> maybeResponse = requestManager.getResponse(requestId); assertTrue(String.format("Response for request %s does not exist", requestId), !maybeResponse.isPresent()); return maybeResponse; } @Test public void testNonExistentLoadBalancerGroup(RequestManager requestManager, BaragonRequestWorker requestWorker) { final String requestId = "test-126"; Set<String> lbGroup = new HashSet<>(); lbGroup.add(FAKE_LB_GROUP); final BaragonService service = new BaragonService("testservice1", Collections.<String>emptyList(), "/test", lbGroup, Collections.<String, Object>emptyMap()); final UpstreamInfo upstream = new UpstreamInfo("testhost:8080", Optional.of(requestId), Optional.<String>absent()); final BaragonRequest request = new BaragonRequest(requestId, service, ImmutableList.of(upstream), ImmutableList.<UpstreamInfo>of(), Optional.<String>absent()); try { assertResponseStateAbsent(requestManager, requestId); LOG.info("Going to enqueue request: {}", request); requestManager.enqueueRequest(request); assertResponseStateExists(requestManager, requestId, BaragonRequestState.WAITING); requestWorker.run(); assertResponseStateExists(requestManager, requestId, BaragonRequestState.INVALID_REQUEST_NOOP); } catch (Exception e) { throw Throwables.propagate(e); } } @Test public void testPreexistingResponse(RequestManager requestManager) throws RequestAlreadyEnqueuedException, InvalidRequestActionException, InvalidUpstreamsException { final String requestId = "test-127"; Set<String> lbGroup = new HashSet<>(); lbGroup.add(FAKE_LB_GROUP); final BaragonService service = new BaragonService("testservice2", Collections.<String>emptyList(), "/test", lbGroup, Collections.<String, Object>emptyMap()); final UpstreamInfo upstream = new UpstreamInfo("testhost:8080", Optional.of(requestId), Optional.<String>absent()); final BaragonRequest request = new BaragonRequest(requestId, service, ImmutableList.of(upstream), ImmutableList.<UpstreamInfo>of(), Optional.<String>absent()); BaragonResponse response = requestManager.enqueueRequest(request); BaragonResponse repeatResponse = requestManager.enqueueRequest(request); assertEquals(repeatResponse, response); } @Test public void testBasePathConflicts(RequestManager requestManager, BaragonRequestWorker requestWorker, BaragonLoadBalancerDatastore loadBalancerDatastore) { loadBalancerDatastore.setBasePathServiceId(REAL_LB_GROUP, "/foo", "foo-service"); final String requestId = "test-128"; Set<String> lbGroup = new HashSet<>(); lbGroup.add(REAL_LB_GROUP); final BaragonService service = new BaragonService("testservice3", Collections.<String>emptyList(), "/foo", lbGroup, Collections.<String, Object>emptyMap()); final UpstreamInfo upstream = new UpstreamInfo("testhost:8080", Optional.of(requestId), Optional.<String>absent()); final BaragonRequest request = new BaragonRequest(requestId, service, ImmutableList.of(upstream), ImmutableList.<UpstreamInfo>of(), Optional.<String>absent()); try { assertResponseStateAbsent(requestManager, requestId); LOG.info("Going to enqueue request: {}", request); requestManager.enqueueRequest(request); assertResponseStateExists(requestManager, requestId, BaragonRequestState.WAITING); requestWorker.run(); assertResponseStateExists(requestManager, requestId, BaragonRequestState.INVALID_REQUEST_NOOP); } catch (Exception e) { throw Throwables.propagate(e); } } @Test public void testAdditionalPathConflicts(RequestManager requestManager, BaragonRequestWorker requestWorker, BaragonLoadBalancerDatastore loadBalancerDatastore) { loadBalancerDatastore.setBasePathServiceId(REAL_LB_GROUP, "/some-other-path", "foo-service"); final String requestId = "test-129"; Set<String> lbGroup = new HashSet<>(); lbGroup.add(REAL_LB_GROUP); final BaragonService service = new BaragonService("testservice4", Collections.<String>emptyList(), "/foo", Collections.singletonList("/some-other-path"), lbGroup, Collections.<String, Object>emptyMap(), Optional.<String>absent(), Collections.<String>emptySet()); final UpstreamInfo upstream = new UpstreamInfo("testhost:8080", Optional.of(requestId), Optional.<String>absent()); final BaragonRequest request = new BaragonRequest(requestId, service, ImmutableList.of(upstream), ImmutableList.<UpstreamInfo>of(), Optional.<String>absent()); try { assertResponseStateAbsent(requestManager, requestId); LOG.info("Going to enqueue request: {}", request); requestManager.enqueueRequest(request); assertResponseStateExists(requestManager, requestId, BaragonRequestState.WAITING); requestWorker.run(); assertResponseStateExists(requestManager, requestId, BaragonRequestState.INVALID_REQUEST_NOOP); } catch (Exception e) { throw Throwables.propagate(e); } } }