Skip to content

Commit

Permalink
Merge pull request #11886 from jetty/fix/12.0.x/cross-context-testing-2
Browse files Browse the repository at this point in the history
Initial work for Cross Context Dispatch testing suite
  • Loading branch information
joakime authored Jun 19, 2024
2 parents 9db54aa + 7011827 commit 422d73d
Show file tree
Hide file tree
Showing 50 changed files with 3,061 additions and 0 deletions.
1 change: 1 addition & 0 deletions tests/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
<module>jetty-jmh</module>
<module>jetty-test-multipart</module>
<module>jetty-test-session-common</module>
<module>test-cross-context-dispatch</module>
<module>test-distribution</module>
<module>test-integration</module>
<module>test-jpms</module>
Expand Down
31 changes: 31 additions & 0 deletions tests/test-cross-context-dispatch/ccd-common/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.eclipse.jetty.tests.ccd</groupId>
<artifactId>test-cross-context-dispatch</artifactId>
<version>12.0.11-SNAPSHOT</version>
</parent>
<artifactId>ccd-common</artifactId>
<packaging>jar</packaging>
<name>Tests :: Cross Context Dispatch :: Common</name>

<dependencies>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-server</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-session</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-slf4j-impl</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,215 @@
//
// ========================================================================
// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others.
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
// which is available at https://www.apache.org/licenses/LICENSE-2.0.
//
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
// ========================================================================
//

package org.eclipse.jetty.tests.ccd.common;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Deque;
import java.util.List;
import java.util.concurrent.LinkedBlockingDeque;

public class DispatchPlan
{
private final Deque<Step> steps = new LinkedBlockingDeque<>();
private final List<String> events = new ArrayList<>();
private final List<String> expectedEvents = new ArrayList<>();
private final List<Property> expectedProperties = new ArrayList<>();
private final List<String> expectedOutput = new ArrayList<>();
private HttpRequest requestStep;
private String id;
private String expectedContentType;
// if true, assert that all Session.id seen in request attributes are the same id.
private boolean expectedSessionIds;

public DispatchPlan()
{
}

public static DispatchPlan read(Path inputText) throws IOException
{
DispatchPlan plan = new DispatchPlan();

plan.id = inputText.getFileName().toString();

for (String line : Files.readAllLines(inputText, StandardCharsets.UTF_8))
{
if (line.startsWith("#"))
continue; // skip
if (line.startsWith("REQUEST|"))
{
plan.setRequestStep(HttpRequest.parse(line));
}
else if (line.startsWith("STEP|"))
{
plan.addStep(Step.parse(line));
}
else if (line.startsWith("EXPECTED_CONTENT_TYPE|"))
{
plan.setExpectedContentType(dropType(line));
}
else if (line.startsWith("EXPECTED_EVENT|"))
{
plan.addExpectedEvent(dropType(line));
}
else if (line.startsWith("EXPECTED_PROP|"))
{
plan.addExpectedProperty(Property.parse(line));
}
else if (line.startsWith("EXPECTED_OUTPUT|"))
{
plan.addExpectedOutput(dropType(line));
}
else if (line.startsWith("EXPECTED_SESSION_IDS|"))
{
plan.setExpectedSessionIds(Boolean.parseBoolean(dropType(line)));
}
}
return plan;
}

private static String dropType(String line)
{
int idx = line.indexOf("|");
return line.substring(idx + 1);
}

public void addEvent(String format, Object... args)
{
events.add(String.format(format, args));
}

public void addExpectedEvent(String event)
{
expectedEvents.add(event);
}

public void addExpectedOutput(String output)
{
expectedOutput.add(output);
}

public void addExpectedProperty(String name, String value)
{
expectedProperties.add(new Property(name, value));
}

public void addExpectedProperty(Property property)
{
expectedProperties.add(property);
}

public void addStep(Step step)
{
steps.add(step);
}

public List<String> getEvents()
{
return events;
}

public String getExpectedContentType()
{
return expectedContentType;
}

public void setExpectedContentType(String expectedContentType)
{
this.expectedContentType = expectedContentType;
}

public List<String> getExpectedEvents()
{
return expectedEvents;
}

public void setExpectedEvents(String[] events)
{
expectedEvents.clear();
expectedEvents.addAll(List.of(events));
}

public List<String> getExpectedOutput()
{
return expectedOutput;
}

public void setExpectedOutput(String[] output)
{
expectedOutput.clear();
expectedOutput.addAll(List.of(output));
}

public List<Property> getExpectedProperties()
{
return expectedProperties;
}

public void setExpectedProperties(Property[] properties)
{
expectedProperties.clear();
expectedProperties.addAll(List.of(properties));
}

public HttpRequest getRequestStep()
{
return requestStep;
}

public void setRequestStep(HttpRequest requestStep)
{
this.requestStep = requestStep;
}

public Deque<Step> getSteps()
{
return steps;
}

public void setSteps(Step[] stepArr)
{
steps.clear();
for (Step step: stepArr)
steps.add(step);
}

public boolean isExpectedSessionIds()
{
return expectedSessionIds;
}

public void setExpectedSessionIds(boolean expectedSessionIds)
{
this.expectedSessionIds = expectedSessionIds;
}

public String id()
{
return id;
}

public Step popStep()
{
return steps.pollFirst();
}

@Override
public String toString()
{
return "DispatchPlan[id=" + id + "]";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
//
// ========================================================================
// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others.
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
// which is available at https://www.apache.org/licenses/LICENSE-2.0.
//
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
// ========================================================================
//

package org.eclipse.jetty.tests.ccd.common;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;

import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Response;
import org.eclipse.jetty.util.Callback;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class DispatchPlanHandler extends Handler.Wrapper
{
private static final Logger LOG = LoggerFactory.getLogger(DispatchPlanHandler.class);
private Path plansDir;

public Path getPlansDir()
{
return plansDir;
}

public void setPlansDir(Path plansDir)
{
this.plansDir = plansDir;
}

public void setPlansDir(String plansDir)
{
this.setPlansDir(Path.of(plansDir));
}

@Override
public boolean handle(Request request, Response response, Callback callback) throws Exception
{
DispatchPlan dispatchPlan = (DispatchPlan)request.getAttribute(DispatchPlan.class.getName());

if (dispatchPlan == null)
{
String planName = request.getHeaders().get("X-DispatchPlan");
if (planName != null)
{
Path planPath = plansDir.resolve(planName);
if (!Files.isRegularFile(planPath))
{
callback.failed(new IOException("Unable to find: " + planPath));
}
dispatchPlan = DispatchPlan.read(planPath);
dispatchPlan.addEvent("Initial plan: %s", planName);
request.setAttribute(DispatchPlan.class.getName(), dispatchPlan);
}
else
{
LOG.info("Missing Request Header [X-DispatchPlan], skipping DispatchPlan behaviors for this request: {}", request.getHttpURI().toURI());
}
}

if (dispatchPlan != null)
dispatchPlan.addEvent("DispatchPlanHandler.handle() method=%s path-query=%s", request.getMethod(), request.getHttpURI().getPathQuery());

return super.handle(request, response, callback);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//
// ========================================================================
// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others.
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
// which is available at https://www.apache.org/licenses/LICENSE-2.0.
//
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
// ========================================================================
//

package org.eclipse.jetty.tests.ccd.common;

public enum DispatchType
{
INCLUDE,
FORWARD;
}
Loading

0 comments on commit 422d73d

Please sign in to comment.