Skip to content

Commit

Permalink
Update to the latest protocol-state-fuzzer which uses generics (#107)
Browse files Browse the repository at this point in the history
* Update inputs, outputs and add two new classes

* Update mapper related classes

* Update sul related classes

* Update alphabet pojo

* Update outer classes

* Update setup_fuzzer pointing to generics branch

* Update according to generic machine model

* Introduce EdhocMapperComposer and simplify some things

* Simplify EdhocSul

* Use anonymous classes for empty SulAdapterConfig

* Update protocol-state-fuzzer setup

* Bump to the latest commit (21/2/2025) of PSF

---------

Co-authored-by: actyp <[email protected]>
  • Loading branch information
kostis and actyp authored Mar 1, 2025
1 parent e4faa87 commit 1836551
Show file tree
Hide file tree
Showing 32 changed files with 361 additions and 220 deletions.
5 changes: 2 additions & 3 deletions scripts/setup_fuzzer.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,14 @@ readonly BASE_DIR
setup_psf() {
# setup protocol-state-fuzzer library

# this is the commit _just_ before Generics were introduced
CHECKOUT="398c9bc526c94294569e46286d43692b5171c175"
CHECKOUT="d4d5730bbd9f7f93d8e9eee5165592586e03c833"

set -e
cd "${BASE_DIR}"
git clone "https://github.com/protocol-fuzzing/protocol-state-fuzzer.git"
cd protocol-state-fuzzer
git checkout ${CHECKOUT}
mvn install -DskipTests
bash ./install.sh

cd "${BASE_DIR}"
rm -rf ./protocol-state-fuzzer/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,11 @@
public class EdhocDotProcessor {
private static final Logger LOGGER = LogManager.getLogger();

public static void beautify(LearnerResult learnerResult) {
public static void beautify(LearnerResult<?> learnerResult) {
if (learnerResult.isFromTest()) {
return;
}

if (learnerResult.isEmpty()) {
LOGGER.warn("Provided empty LearnerResult");
return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ public static void main(String[] args) {
MultiBuilder mb = new MultiBuilder();
String[] parentLoggers = {Main.class.getPackageName()};

CommandLineParser commandLineParser = new CommandLineParser(mb, mb, mb, mb);
CommandLineParser<?> commandLineParser = new CommandLineParser<>(mb, mb, mb, mb);
commandLineParser.setExternalParentLoggers(parentLoggers);

commandLineParser.parse(args, true, List.of(EdhocDotProcessor::beautify));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,14 @@
import com.github.protocolfuzzing.edhocfuzzer.components.sul.core.config.EdhocSulClientConfig;
import com.github.protocolfuzzing.edhocfuzzer.components.sul.core.config.EdhocSulServerConfig;
import com.github.protocolfuzzing.edhocfuzzer.components.sul.mapper.config.EdhocMapperConfig;
import com.github.protocolfuzzing.edhocfuzzer.components.sul.mapper.context.EdhocExecutionContext;
import com.github.protocolfuzzing.edhocfuzzer.components.sul.mapper.symbols.inputs.EdhocInput;
import com.github.protocolfuzzing.edhocfuzzer.components.sul.mapper.symbols.outputs.EdhocOutput;
import com.github.protocolfuzzing.protocolstatefuzzer.components.learner.alphabet.AlphabetBuilder;
import com.github.protocolfuzzing.protocolstatefuzzer.components.learner.alphabet.AlphabetBuilderStandard;
import com.github.protocolfuzzing.protocolstatefuzzer.components.learner.alphabet.xml.AlphabetSerializerXml;
import com.github.protocolfuzzing.protocolstatefuzzer.components.learner.config.LearnerConfigStandard;
import com.github.protocolfuzzing.protocolstatefuzzer.components.learner.statistics.MealyMachineWrapper;
import com.github.protocolfuzzing.protocolstatefuzzer.components.sul.core.SulBuilder;
import com.github.protocolfuzzing.protocolstatefuzzer.components.sul.core.SulWrapper;
import com.github.protocolfuzzing.protocolstatefuzzer.components.sul.core.SulWrapperStandard;
Expand All @@ -24,21 +28,27 @@
import com.github.protocolfuzzing.protocolstatefuzzer.statefuzzer.core.config.StateFuzzerServerConfigStandard;
import com.github.protocolfuzzing.protocolstatefuzzer.statefuzzer.testrunner.core.TestRunner;
import com.github.protocolfuzzing.protocolstatefuzzer.statefuzzer.testrunner.core.TestRunnerBuilder;
import com.github.protocolfuzzing.protocolstatefuzzer.statefuzzer.testrunner.core.TestRunnerStandard;
import com.github.protocolfuzzing.protocolstatefuzzer.statefuzzer.testrunner.core.config.TestRunnerConfigStandard;
import com.github.protocolfuzzing.protocolstatefuzzer.statefuzzer.testrunner.core.config.TestRunnerEnabler;
import com.github.protocolfuzzing.protocolstatefuzzer.statefuzzer.testrunner.timingprobe.TimingProbe;
import com.github.protocolfuzzing.protocolstatefuzzer.statefuzzer.testrunner.timingprobe.TimingProbeBuilder;
import com.github.protocolfuzzing.protocolstatefuzzer.statefuzzer.testrunner.timingprobe.TimingProbeStandard;
import com.github.protocolfuzzing.protocolstatefuzzer.statefuzzer.testrunner.timingprobe.config.TimingProbeConfigStandard;
import com.github.protocolfuzzing.protocolstatefuzzer.statefuzzer.testrunner.timingprobe.config.TimingProbeEnabler;

public class MultiBuilder implements StateFuzzerConfigBuilder, StateFuzzerBuilder, TestRunnerBuilder, TimingProbeBuilder {
public class MultiBuilder implements
StateFuzzerConfigBuilder,
StateFuzzerBuilder<MealyMachineWrapper<EdhocInput, EdhocOutput>>,
TestRunnerBuilder,
TimingProbeBuilder {

protected AlphabetBuilder alphabetBuilder = new AlphabetBuilderStandard(
new AlphabetSerializerXml<>(EdhocAlphabetPojoXml.class)
protected AlphabetBuilder<EdhocInput> alphabetBuilder = new AlphabetBuilderStandard<>(
new AlphabetSerializerXml<EdhocInput, EdhocAlphabetPojoXml>(EdhocInput.class, EdhocAlphabetPojoXml.class)
);

protected SulBuilder sulBuilder = new EdhocSulBuilder();
protected SulWrapper sulWrapper = new SulWrapperStandard();
protected SulBuilder<EdhocInput, EdhocOutput, EdhocExecutionContext> sulBuilder = new EdhocSulBuilder();
protected SulWrapper<EdhocInput, EdhocOutput, EdhocExecutionContext> sulWrapper = new SulWrapperStandard<>();

@Override
public StateFuzzerClientConfig buildClientConfig() {
Expand All @@ -61,19 +71,19 @@ public StateFuzzerServerConfig buildServerConfig() {
}

@Override
public StateFuzzer build(StateFuzzerEnabler stateFuzzerEnabler) {
return new StateFuzzerStandard(
new StateFuzzerComposerStandard(stateFuzzerEnabler, alphabetBuilder, sulBuilder, sulWrapper).initialize()
public StateFuzzer<MealyMachineWrapper<EdhocInput, EdhocOutput>> build(StateFuzzerEnabler stateFuzzerEnabler) {
return new StateFuzzerStandard<>(
new StateFuzzerComposerStandard<>(stateFuzzerEnabler, alphabetBuilder, sulBuilder, sulWrapper).initialize()
);
}

@Override
public TestRunner build(TestRunnerEnabler testRunnerEnabler) {
return new TestRunner(testRunnerEnabler, alphabetBuilder, sulBuilder, sulWrapper).initialize();
return new TestRunnerStandard<>(testRunnerEnabler, alphabetBuilder, sulBuilder, sulWrapper).initialize();
}

@Override
public TimingProbe build(TimingProbeEnabler timingProbeEnabler) {
return new TimingProbe(timingProbeEnabler, alphabetBuilder, sulBuilder, sulWrapper).initialize();
return new TimingProbeStandard<>(timingProbeEnabler, alphabetBuilder, sulBuilder, sulWrapper).initialize();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,17 @@

import com.github.protocolfuzzing.edhocfuzzer.components.sul.mapper.symbols.inputs.*;
import com.github.protocolfuzzing.protocolstatefuzzer.components.learner.alphabet.xml.AlphabetPojoXml;
import com.github.protocolfuzzing.protocolstatefuzzer.components.sul.mapper.abstractsymbols.AbstractInput;
import jakarta.xml.bind.annotation.*;
import jakarta.xml.bind.annotation.XmlAccessType;
import jakarta.xml.bind.annotation.XmlAccessorType;
import jakarta.xml.bind.annotation.XmlElement;
import jakarta.xml.bind.annotation.XmlElements;
import jakarta.xml.bind.annotation.XmlRootElement;

import java.util.List;

@XmlRootElement(name = "alphabet")
@XmlAccessorType(XmlAccessType.FIELD)
public class EdhocAlphabetPojoXml extends AlphabetPojoXml {
public class EdhocAlphabetPojoXml extends AlphabetPojoXml<EdhocInput> {
@XmlElements(value = {
@XmlElement(type = EdhocMessage1Input.class, name = "EdhocMessage1Input"),
@XmlElement(type = EdhocMessage2Input.class, name = "EdhocMessage2Input"),
Expand All @@ -21,16 +24,16 @@ public class EdhocAlphabetPojoXml extends AlphabetPojoXml {
@XmlElement(type = CoapAppMessageInput.class, name = "CoapAppMessageInput"),
@XmlElement(type = CoapEmptyMessageInput.class, name = "CoapEmptyMessageInput")
})
protected List<AbstractInput> inputs;
protected List<EdhocInput> inputs;

public EdhocAlphabetPojoXml() {}

public EdhocAlphabetPojoXml(List<AbstractInput> inputs) {
public EdhocAlphabetPojoXml(List<EdhocInput> inputs) {
this.inputs = inputs;
}

@Override
public List<AbstractInput> getInputs(){
public List<EdhocInput> getInputs(){
return inputs;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,25 @@
import com.github.protocolfuzzing.edhocfuzzer.components.sul.core.config.EdhocSulClientConfig;
import com.github.protocolfuzzing.edhocfuzzer.components.sul.mapper.config.EdhocMapperConfig;
import com.github.protocolfuzzing.edhocfuzzer.components.sul.mapper.config.EdhocMapperConnectionConfig;
import com.github.protocolfuzzing.edhocfuzzer.components.sul.mapper.config.ProtocolVersion;
import com.github.protocolfuzzing.edhocfuzzer.components.sul.mapper.connectors.ClientMapperConnector;
import com.github.protocolfuzzing.edhocfuzzer.components.sul.mapper.connectors.EdhocMapperConnector;
import com.github.protocolfuzzing.edhocfuzzer.components.sul.mapper.connectors.ServerMapperConnector;
import com.github.protocolfuzzing.edhocfuzzer.components.sul.mapper.context.ClientMapperState;
import com.github.protocolfuzzing.edhocfuzzer.components.sul.mapper.context.EdhocExecutionContext;
import com.github.protocolfuzzing.edhocfuzzer.components.sul.mapper.context.EdhocMapperState;
import com.github.protocolfuzzing.edhocfuzzer.components.sul.mapper.context.ServerMapperState;
import com.github.protocolfuzzing.edhocfuzzer.components.sul.mapper.mappers.EdhocInputMapper;
import com.github.protocolfuzzing.edhocfuzzer.components.sul.mapper.mappers.EdhocMapperComposer;
import com.github.protocolfuzzing.edhocfuzzer.components.sul.mapper.mappers.EdhocOutputMapper;
import com.github.protocolfuzzing.edhocfuzzer.components.sul.mapper.symbols.inputs.EdhocInput;
import com.github.protocolfuzzing.edhocfuzzer.components.sul.mapper.symbols.outputs.EdhocOutput;
import com.github.protocolfuzzing.edhocfuzzer.components.sul.mapper.symbols.outputs.EdhocOutputBuilder;
import com.github.protocolfuzzing.edhocfuzzer.components.sul.mapper.symbols.outputs.EdhocOutputChecker;
import com.github.protocolfuzzing.edhocfuzzer.components.sul.mapper.symbols.outputs.MessageOutputType;
import com.github.protocolfuzzing.protocolstatefuzzer.components.sul.core.AbstractSul;
import com.github.protocolfuzzing.protocolstatefuzzer.components.sul.core.SulAdapter;
import com.github.protocolfuzzing.protocolstatefuzzer.components.sul.core.config.SulConfig;
import com.github.protocolfuzzing.protocolstatefuzzer.components.sul.mapper.Mapper;
import com.github.protocolfuzzing.protocolstatefuzzer.components.sul.mapper.abstractsymbols.AbstractInput;
import com.github.protocolfuzzing.protocolstatefuzzer.components.sul.mapper.abstractsymbols.AbstractOutput;
import com.github.protocolfuzzing.protocolstatefuzzer.components.sul.mapper.config.MapperConfig;
import com.github.protocolfuzzing.protocolstatefuzzer.components.sul.mapper.context.ExecutionContextStepped;
import com.github.protocolfuzzing.protocolstatefuzzer.components.sul.mapper.mappers.MapperComposer;
import com.github.protocolfuzzing.protocolstatefuzzer.components.sul.core.sulwrappers.DynamicPortProvider;
import com.github.protocolfuzzing.protocolstatefuzzer.utils.CleanupTasks;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
Expand All @@ -30,18 +30,23 @@
import java.io.IOException;
import java.util.concurrent.TimeUnit;

public class EdhocSul extends AbstractSul {
public class EdhocSul implements AbstractSul<EdhocInput, EdhocOutput, EdhocExecutionContext> {
private static final Logger LOGGER = LogManager.getLogger();
protected ExecutionContextStepped executionContextStepped;
protected ProtocolVersion protocolVersion;

protected SulConfig sulConfig;
protected CleanupTasks cleanupTasks;
protected EdhocMapperConfig edhocMapperConfig;
protected EdhocMapperComposer edhocMapperComposer;
protected EdhocExecutionContext edhocExecutionContext;
protected Long originalTimeout;
protected EdhocMapperState edhocMapperState;
protected EdhocMapperConnector edhocMapperConnector;
protected boolean serverWaitForInitialMessageDone;

public EdhocSul(SulConfig sulConfig, CleanupTasks cleanupTasks) {
super(sulConfig, cleanupTasks);
this.protocolVersion = ((EdhocMapperConfig) sulConfig.getMapperConfig()).getProtocolVersion();
this.sulConfig = sulConfig;
this.cleanupTasks = cleanupTasks;
this.edhocMapperConfig = (EdhocMapperConfig) sulConfig.getMapperConfig();
this.originalTimeout = sulConfig.getResponseWait();
}

Expand All @@ -68,7 +73,6 @@ public EdhocSul initialize() {
}

// The connector uses the californium standard configuration
EdhocMapperConfig edhocMapperConfig = (EdhocMapperConfig) sulConfig.getMapperConfig();
if (sulConfig.isFuzzingClient()){
this.edhocMapperConnector = new ServerMapperConnector(edhocMapperConfig.getHostCoapUri(),
edhocMapperConfig.getEdhocCoapResource(), edhocMapperConfig.getAppCoapResource(),
Expand All @@ -78,28 +82,51 @@ public EdhocSul initialize() {
edhocMapperConfig.getAppCoapUri(), this.originalTimeout);
}

this.mapper = buildMapper(sulConfig.getMapperConfig(), this.edhocMapperConnector);
this.edhocMapperComposer = new EdhocMapperComposer (
new EdhocInputMapper(edhocMapperConfig, new EdhocOutputChecker(), edhocMapperConnector),
new EdhocOutputMapper(edhocMapperConfig, new EdhocOutputBuilder(), new EdhocOutputChecker(), edhocMapperConnector)
);

return this;
}

protected Mapper buildMapper(MapperConfig mapperConfig, EdhocMapperConnector edhocMapperConnector) {
return new MapperComposer(
new EdhocInputMapper(mapperConfig, new EdhocOutputChecker(), edhocMapperConnector),
new EdhocOutputMapper(mapperConfig, edhocMapperConnector)
);
@Override
public SulConfig getSulConfig() {
return sulConfig;
}

@Override
public CleanupTasks getCleanupTasks() {
return cleanupTasks;
}

@Override
public EdhocMapperComposer getMapper() {
return edhocMapperComposer;
}

@Override
public void setDynamicPortProvider(DynamicPortProvider dynamicPortProvider) {
throw new RuntimeException("No dynamic port provider available");
}

@Override
public DynamicPortProvider getDynamicPortProvider() {
throw new RuntimeException("No dynamic port provider available");
}

@Override
public SulAdapter getSulAdapter() {
throw new RuntimeException("No sul adapter available");
}

@Override
public void pre() {
LOGGER.debug("SUL 'pre' start");

// mapper config
EdhocMapperConfig edhocMapperConfig = (EdhocMapperConfig) sulConfig.getMapperConfig();

if (sulConfig.isFuzzingClient()) {
ServerMapperConnector serverMapperConnector = (ServerMapperConnector) edhocMapperConnector;
edhocMapperState = new ServerMapperState(protocolVersion, edhocMapperConfig, cleanupTasks).initialize(serverMapperConnector);
edhocMapperState = new ServerMapperState(edhocMapperConfig, cleanupTasks).initialize(serverMapperConnector);

serverWaitForInitialMessageDone = false;
cleanupTasks.submit(serverMapperConnector::shutdown);
Expand All @@ -115,10 +142,10 @@ public void pre() {
}
} else {
ClientMapperConnector clientMapperConnector = (ClientMapperConnector) edhocMapperConnector;
edhocMapperState = new ClientMapperState(protocolVersion, edhocMapperConfig, cleanupTasks).initialize(clientMapperConnector);
edhocMapperState = new ClientMapperState(edhocMapperConfig, cleanupTasks).initialize(clientMapperConnector);
}

this.executionContextStepped = new ExecutionContextStepped(edhocMapperState);
this.edhocExecutionContext = new EdhocExecutionContext(edhocMapperState);

long startWait = sulConfig.getStartWait();
if (startWait > 0) {
Expand All @@ -139,35 +166,31 @@ public void post() {
}

@Override
public AbstractOutput step(AbstractInput abstractInput) {
public EdhocOutput step(EdhocInput abstractInput) {
// In case of server mapper, wait for initial message from client
serverWaitForInitialMessage();

LOGGER.debug("SUL 'step' start");

executionContextStepped.addStepContext();
Mapper preferredMapper = abstractInput.getPreferredMapper(sulConfig);
if (preferredMapper == null) {
preferredMapper = this.mapper;
}
edhocExecutionContext.addStepContext();

if (!executionContextStepped.isExecutionEnabled()) {
return ((MapperComposer) this.mapper).getOutputMapper().disabled();
if (!edhocExecutionContext.isExecutionEnabled()) {
return edhocMapperComposer.getOutputMapper().disabled();
}

AbstractOutput abstractOutput = executeInput(abstractInput, preferredMapper);
EdhocOutput abstractOutput = executeInput(abstractInput);

if (abstractOutput.equals(AbstractOutput.disabled()) || !executionContextStepped.isExecutionEnabled()) {
if (edhocMapperComposer.getOutputChecker().isDisabled(abstractOutput) || !edhocExecutionContext.isExecutionEnabled()) {
// this should lead to a disabled sink state
executionContextStepped.disableExecution();
edhocExecutionContext.disableExecution();
}

LOGGER.debug("SUL 'step' end");

return abstractOutput;
}

protected AbstractOutput executeInput(AbstractInput abstractInput, Mapper mapper) {
protected EdhocOutput executeInput(EdhocInput abstractInput) {
boolean timeoutChanged = false;

// handle timeout from extendedWait and from inputResponse
Expand All @@ -180,7 +203,7 @@ protected AbstractOutput executeInput(AbstractInput abstractInput, Mapper mapper
timeoutChanged = true;
}

AbstractOutput abstractOutput = mapper.execute(abstractInput, executionContextStepped);
EdhocOutput abstractOutput = edhocMapperComposer.execute(abstractInput, edhocExecutionContext);

// reset timeout
if (timeoutChanged) {
Expand All @@ -200,12 +223,11 @@ protected void serverWaitForInitialMessage() {
return;
}

MapperComposer mapperComposer = (MapperComposer) mapper;
ServerMapperConnector serverMapperConnector = (ServerMapperConnector) edhocMapperConnector;
EdhocOutputChecker edhocOutputChecker = (EdhocOutputChecker) mapperComposer.getAbstractOutputChecker();
EdhocOutputChecker edhocOutputChecker = edhocMapperComposer.getOutputChecker();

serverMapperConnector.waitForClientMessage();
AbstractOutput abstractOutput = mapperComposer.getOutputMapper().receiveOutput(executionContextStepped);
EdhocOutput abstractOutput = edhocMapperComposer.getOutputMapper().receiveOutput(edhocExecutionContext);
boolean isExpectedMessage = edhocOutputChecker.isMessage(abstractOutput, expectedMessageType);

if (!isExpectedMessage) {
Expand All @@ -216,4 +238,5 @@ protected void serverWaitForInitialMessage() {
LOGGER.debug("Received {} from client", expectedMessageType);
serverWaitForInitialMessageDone = true;
}

}
Loading

0 comments on commit 1836551

Please sign in to comment.