mirror of
https://gitlab.kit.edu/uskyk/typicalc.git
synced 2024-11-08 18:30:42 +00:00
Fuzzing setup + documentation
This commit is contained in:
parent
bd8a7a26cf
commit
3f07a6d234
2
.gitignore
vendored
2
.gitignore
vendored
@ -18,3 +18,5 @@ drivers/
|
|||||||
# Error screenshots generated by TestBench for failed integration tests
|
# Error screenshots generated by TestBench for failed integration tests
|
||||||
error-screenshots/
|
error-screenshots/
|
||||||
webpack.generated.js
|
webpack.generated.js
|
||||||
|
|
||||||
|
/fuzz-results
|
||||||
|
45
README.md
45
README.md
@ -1,11 +1,11 @@
|
|||||||
# Typicalc
|
# Typicalc
|
||||||
|
|
||||||
The project is a standard Maven project, so you can import it to your IDE of choice. [Read more how to set up a development environment](https://vaadin.com/docs/v14/flow/installing/installing-overview.html) for Vaadin projects (Windows, Linux, macOS).
|
The project is a standard Maven project, so you can import it to your IDE of choice.
|
||||||
|
[Read more how to set up a development environment](https://vaadin.com/docs/v18/flow/installing/installing-overview.html) for Vaadin projects (Windows, Linux, macOS).
|
||||||
|
|
||||||
[To Vaadin documentation](https://vaadin.com/docs-beta/latest/flow/overview/)
|
[To Vaadin documentation](https://vaadin.com/docs-beta/latest/flow/overview/)
|
||||||
|
|
||||||
|
## Running and debugging the application
|
||||||
## Running and debugging the applcation
|
|
||||||
|
|
||||||
### Running the application from the command line.
|
### Running the application from the command line.
|
||||||
To run from the command line, use `mvn` and open http://localhost:8080 in your browser.
|
To run from the command line, use `mvn` and open http://localhost:8080 in your browser.
|
||||||
@ -15,7 +15,7 @@ To run from the command line, use `mvn` and open http://localhost:8080 in your b
|
|||||||
- Right click on the Application class
|
- Right click on the Application class
|
||||||
- Select "Debug 'Application.main()'" from the list
|
- Select "Debug 'Application.main()'" from the list
|
||||||
|
|
||||||
After the application has started, you can view your it at http://localhost:8080/ in your browser.
|
After the application has started, you can view it at http://localhost:8080/ in your browser.
|
||||||
You can now also attach break points in code for debugging purposes, by clicking next to a line number in any source file.
|
You can now also attach break points in code for debugging purposes, by clicking next to a line number in any source file.
|
||||||
|
|
||||||
### Running and debugging the application in Eclipse
|
### Running and debugging the application in Eclipse
|
||||||
@ -27,13 +27,29 @@ Do not worry if the debugger breaks at a `SilentExitException`. This is a Spring
|
|||||||
After the application has started, you can view your it at http://localhost:8080/ in your browser.
|
After the application has started, you can view your it at http://localhost:8080/ in your browser.
|
||||||
You can now also attach break points in code for debugging purposes, by clicking next to a line number in any source file.
|
You can now also attach break points in code for debugging purposes, by clicking next to a line number in any source file.
|
||||||
|
|
||||||
## What next?
|
## Fuzzing with [JQF](https://github.com/rohanpadhye/JQF)
|
||||||
|
|
||||||
[vaadin.com](https://vaadin.com) has lots of material to help you get you started:
|
### [Zest](https://github.com/rohanpadhye/JQF/wiki/Fuzzing-with-Zest)
|
||||||
|
|
||||||
- Follow the tutorials in [vaadin.com/tutorials](https://vaadin.com/tutorials). Especially [vaadin.com/tutorials/getting-started-with-flow](https://vaadin.com/tutorials/getting-started-with-flow) is good for getting a grasp of the basic Vaadin concepts.
|
Run:
|
||||||
- Read the documentation in [vaadin.com/docs](https://vaadin.com/docs).
|
```
|
||||||
- For a bigger Vaadin application example, check out the Full Stack App starter from [vaadin.com/start](https://vaadin.com/start).
|
mvn test-compile jqf:fuzz -Dclass=edu.kit.typicalc.model.parser.LambdaParserFuzzTest -Dmethod=testInference
|
||||||
|
```
|
||||||
|
|
||||||
|
This will use the `LambdaTermGenerator` to create random lambda terms that are then passed to the `ModelImpl`.
|
||||||
|
|
||||||
|
### [AFL](https://lcamtuf.coredump.cx/afl/)
|
||||||
|
|
||||||
|
First install the necessary JQF tools: https://github.com/rohanpadhye/jqf/wiki/Fuzzing-with-AFL
|
||||||
|
|
||||||
|
Remove the `@Ignore` annotation in `LambdaParserFuzzTest` and run:
|
||||||
|
```
|
||||||
|
mvn test-compile
|
||||||
|
jqf-afl-fuzz -c target/test-classes:target/classes -i src/test/resources/terms/ edu.kit.typicalc.model.parser.LambdaParserFuzzTest testLambdaParserAFL
|
||||||
|
```
|
||||||
|
|
||||||
|
Generated inputs are stored in `fuzz-results/queue/`.
|
||||||
|
More samples can be added to `src/test/resources/terms/` to speed up the process.
|
||||||
|
|
||||||
## Deploying using Docker
|
## Deploying using Docker
|
||||||
|
|
||||||
@ -48,3 +64,14 @@ Once the Docker image is correctly built, you can test it locally using
|
|||||||
```
|
```
|
||||||
docker run -p 8080:8080 myapp:latest
|
docker run -p 8080:8080 myapp:latest
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Deploying using a JAR
|
||||||
|
|
||||||
|
First build the project:
|
||||||
|
```
|
||||||
|
mvn package -Pproduction
|
||||||
|
```
|
||||||
|
Then run the server:
|
||||||
|
```
|
||||||
|
java -jar target/typicalc-1.0-SNAPSHOT.jar
|
||||||
|
```
|
||||||
|
11
pom.xml
11
pom.xml
@ -92,6 +92,12 @@
|
|||||||
<artifactId>spring-boot-devtools</artifactId>
|
<artifactId>spring-boot-devtools</artifactId>
|
||||||
<optional>true</optional>
|
<optional>true</optional>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>edu.berkeley.cs.jqf</groupId>
|
||||||
|
<artifactId>jqf-fuzz</artifactId>
|
||||||
|
<version>1.6</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.vaadin</groupId>
|
<groupId>com.vaadin</groupId>
|
||||||
<artifactId>vaadin-testbench</artifactId>
|
<artifactId>vaadin-testbench</artifactId>
|
||||||
@ -159,6 +165,11 @@
|
|||||||
<build>
|
<build>
|
||||||
<defaultGoal>spring-boot:run</defaultGoal>
|
<defaultGoal>spring-boot:run</defaultGoal>
|
||||||
<plugins>
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>edu.berkeley.cs.jqf</groupId>
|
||||||
|
<artifactId>jqf-maven-plugin</artifactId>
|
||||||
|
<version>1.6</version>
|
||||||
|
</plugin>
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
server.port=${PORT:8080}
|
server.port=${PORT:8080}
|
||||||
|
server.servlet.session.persistent=false
|
||||||
logging.level.org.atmosphere = warn
|
logging.level.org.atmosphere = warn
|
||||||
spring.mustache.check-template-location = false
|
spring.mustache.check-template-location = false
|
||||||
spring.devtools.add-properties = false
|
spring.devtools.add-properties = false
|
||||||
|
|
||||||
# vaadin.whitelisted-packages= org/vaadin/example
|
|
||||||
|
@ -0,0 +1,65 @@
|
|||||||
|
package edu.kit.typicalc.model.parser;
|
||||||
|
|
||||||
|
import edu.berkeley.cs.jqf.fuzz.Fuzz;
|
||||||
|
import edu.berkeley.cs.jqf.fuzz.JQF;
|
||||||
|
import edu.kit.typicalc.model.Model;
|
||||||
|
import edu.kit.typicalc.model.ModelImpl;
|
||||||
|
import edu.kit.typicalc.model.TypeInfererInterface;
|
||||||
|
import edu.kit.typicalc.model.step.InferenceStep;
|
||||||
|
import edu.kit.typicalc.model.term.LambdaTerm;
|
||||||
|
import edu.kit.typicalc.util.Result;
|
||||||
|
import org.junit.Ignore;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
import com.pholser.junit.quickcheck.*;
|
||||||
|
|
||||||
|
@RunWith(JQF.class)
|
||||||
|
public class LambdaParserFuzzTest {
|
||||||
|
/**
|
||||||
|
* Runs the type inference algorithm and gets the first inference step.
|
||||||
|
* Only validates that the algorithm produced something.
|
||||||
|
*
|
||||||
|
* @param term lambda term
|
||||||
|
*/
|
||||||
|
@Fuzz
|
||||||
|
public void testInference(@From(LambdaTermGenerator.class) String term) {
|
||||||
|
Model model = new ModelImpl();
|
||||||
|
Result<TypeInfererInterface, ParseError> typer = model.getTypeInferer(term, new HashMap<>());
|
||||||
|
InferenceStep first = typer.unwrap().getFirstInferenceStep();
|
||||||
|
}
|
||||||
|
|
||||||
|
// this is how to rerun a specific fuzz result
|
||||||
|
/*
|
||||||
|
@Fuzz(repro="target/fuzz-results/edu.kit.typicalc.model.parser.LambdaParserFuzzTest/testInference/corpus/id_000066")
|
||||||
|
public void testWithGenerator(@From(LambdaTermGenerator.class) String code) {
|
||||||
|
System.out.println(code);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
@Fuzz
|
||||||
|
@Ignore // remove if you intend to use AFL
|
||||||
|
public void testLambdaParserAFL(InputStream input) {
|
||||||
|
String term;
|
||||||
|
try {
|
||||||
|
term = new String(input.readAllBytes());
|
||||||
|
} catch (Throwable t) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
LambdaParser parser = new LambdaParser(term);
|
||||||
|
Result<LambdaTerm, ParseError> result = parser.parse();
|
||||||
|
if (result.isOk()) {
|
||||||
|
LambdaTerm term1 = result.unwrap();
|
||||||
|
String sameTerm = term1.toString();
|
||||||
|
LambdaParser parser2 = new LambdaParser(sameTerm);
|
||||||
|
Result<LambdaTerm, ParseError> result2 = parser2.parse();
|
||||||
|
LambdaTerm term2 = result2.unwrap();
|
||||||
|
if (!term2.equals(term1)) {
|
||||||
|
throw new IllegalStateException("results differ, when parsing: " + term);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,53 @@
|
|||||||
|
package edu.kit.typicalc.model.parser;
|
||||||
|
|
||||||
|
import com.pholser.junit.quickcheck.generator.GenerationStatus;
|
||||||
|
import com.pholser.junit.quickcheck.generator.Generator;
|
||||||
|
import com.pholser.junit.quickcheck.random.SourceOfRandomness;
|
||||||
|
import edu.kit.typicalc.model.term.AbsTerm;
|
||||||
|
import edu.kit.typicalc.model.term.AppTerm;
|
||||||
|
import edu.kit.typicalc.model.term.IntegerTerm;
|
||||||
|
import edu.kit.typicalc.model.term.LambdaTerm;
|
||||||
|
import edu.kit.typicalc.model.term.LetTerm;
|
||||||
|
import edu.kit.typicalc.model.term.VarTerm;
|
||||||
|
|
||||||
|
public class LambdaTermGenerator extends Generator<String> {
|
||||||
|
|
||||||
|
public LambdaTermGenerator() {
|
||||||
|
super(String.class); // Register the type of objects that we can create
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final String[] VARIABLES = new String[]{"x", "y", "z"};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate a random lambda term.
|
||||||
|
*
|
||||||
|
* @param random source of randomness
|
||||||
|
* @param status not used
|
||||||
|
* @return a random lambda term
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String generate(SourceOfRandomness random, GenerationStatus status) {
|
||||||
|
return generateReal(random).toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private LambdaTerm generateReal(SourceOfRandomness random) {
|
||||||
|
if (random.nextInt(1, 7) < 3) {
|
||||||
|
LambdaTerm one = generateReal(random);
|
||||||
|
LambdaTerm two = generateReal(random);
|
||||||
|
if (random.nextInt(1, 10) < 8) {
|
||||||
|
return new AppTerm(one, two);
|
||||||
|
} else {
|
||||||
|
return new LetTerm(new VarTerm(random.choose(VARIABLES)), one, two);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (random.nextBoolean()) {
|
||||||
|
LambdaTerm one = generateReal(random);
|
||||||
|
return new AbsTerm(new VarTerm(random.choose(VARIABLES)), one);
|
||||||
|
} else if (random.nextBoolean()) {
|
||||||
|
return new VarTerm(random.choose(VARIABLES));
|
||||||
|
} else {
|
||||||
|
return new IntegerTerm(5);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
1
src/test/resources/terms/abs
Normal file
1
src/test/resources/terms/abs
Normal file
@ -0,0 +1 @@
|
|||||||
|
λx. x
|
1
src/test/resources/terms/app
Normal file
1
src/test/resources/terms/app
Normal file
@ -0,0 +1 @@
|
|||||||
|
x y
|
1
src/test/resources/terms/complex
Normal file
1
src/test/resources/terms/complex
Normal file
@ -0,0 +1 @@
|
|||||||
|
(λy. y 5)(λx.x)
|
1
src/test/resources/terms/const
Normal file
1
src/test/resources/terms/const
Normal file
@ -0,0 +1 @@
|
|||||||
|
true
|
1
src/test/resources/terms/let
Normal file
1
src/test/resources/terms/let
Normal file
@ -0,0 +1 @@
|
|||||||
|
let f = λx.x in f 5
|
Loading…
Reference in New Issue
Block a user