@@ -8,9 +8,7 @@ package software.amazon.smithy.rust.codegen.fuzz
88import software.amazon.smithy.build.FileManifest
99import software.amazon.smithy.build.PluginContext
1010import software.amazon.smithy.build.SmithyBuildPlugin
11- import software.amazon.smithy.codegen.core.Symbol
1211import software.amazon.smithy.model.Model
13- import software.amazon.smithy.model.knowledge.NullableIndex
1412import software.amazon.smithy.model.knowledge.TopDownIndex
1513import software.amazon.smithy.model.neighbor.Walker
1614import software.amazon.smithy.model.node.ArrayNode
@@ -20,7 +18,6 @@ import software.amazon.smithy.model.node.ObjectNode
2018import software.amazon.smithy.model.node.StringNode
2119import software.amazon.smithy.model.shapes.MemberShape
2220import software.amazon.smithy.model.shapes.OperationShape
23- import software.amazon.smithy.model.shapes.ServiceShape
2421import software.amazon.smithy.model.shapes.Shape
2522import software.amazon.smithy.model.shapes.ShapeId
2623import software.amazon.smithy.model.traits.HttpPrefixHeadersTrait
@@ -30,37 +27,38 @@ import software.amazon.smithy.model.traits.JsonNameTrait
3027import software.amazon.smithy.model.traits.XmlNameTrait
3128import software.amazon.smithy.protocoltests.traits.HttpRequestTestsTrait
3229import software.amazon.smithy.rust.codegen.core.rustlang.RustModule
33- import software.amazon.smithy.rust.codegen.core.rustlang.RustType
3430import software.amazon.smithy.rust.codegen.core.rustlang.Writable
35- import software.amazon.smithy.rust.codegen.core.smithy.CoreCodegenConfig
36- import software.amazon.smithy.rust.codegen.core.smithy.CoreRustSettings
3731import software.amazon.smithy.rust.codegen.core.smithy.ModuleDocProvider
38- import software.amazon.smithy.rust.codegen.core.smithy.PublicImportSymbolProvider
3932import software.amazon.smithy.rust.codegen.core.smithy.RuntimeConfig
40- import software.amazon.smithy.rust.codegen.core.smithy.RustCrate
41- import software.amazon.smithy.rust.codegen.core.smithy.RustSymbolProvider
42- import software.amazon.smithy.rust.codegen.core.smithy.RustSymbolProviderConfig
43- import software.amazon.smithy.rust.codegen.core.smithy.SymbolVisitor
44- import software.amazon.smithy.rust.codegen.core.smithy.WrappingSymbolProvider
45- import software.amazon.smithy.rust.codegen.core.smithy.mapRustType
4633import software.amazon.smithy.rust.codegen.core.smithy.transformers.OperationNormalizer
4734import software.amazon.smithy.rust.codegen.core.util.getTrait
4835import software.amazon.smithy.rust.codegen.core.util.orNull
49- import software.amazon.smithy.rust.codegen.server.smithy.ServerModuleProvider
5036import software.amazon.smithy.rust.codegen.server.smithy.transformers.AttachValidationExceptionToConstrainedOperationInputsInAllowList
5137import java.nio.file.Path
5238import java.util.Base64
5339import kotlin.streams.toList
5440
55- data class FuzzTarget (val name : String , val relativePath : String ) {
41+ /* *
42+ * Metadata for a TargetCrate: A code generated smithy-rs server for a given model
43+ */
44+ data class TargetCrate (
45+ /* * The name of the Fuzz target */
46+ val name : String ,
47+ /* * Where the server implementation of this target is */
48+ val relativePath : String ,
49+ ) {
5650 companion object {
57- fun fromNode (node : ObjectNode ): FuzzTarget {
51+ fun fromNode (node : ObjectNode ): TargetCrate {
5852 val name = node.expectStringMember(" name" ).value
5953 val relativePath = node.expectStringMember(" relativePath" ).value
60- return FuzzTarget (name, relativePath)
54+ return TargetCrate (name, relativePath)
6155 }
6256 }
6357
58+ /* * The name of the actual `package` from Cargo's perspective.
59+ *
60+ * We need this to make a dependency on it
61+ * */
6462 fun targetPackage (): String {
6563 val path = Path .of(relativePath)
6664 val cargoToml = path.resolve(" Cargo.toml" ).toFile()
@@ -71,20 +69,27 @@ data class FuzzTarget(val name: String, val relativePath: String) {
7169}
7270
7371data class FuzzSettings (
74- val targetCratePath : List <FuzzTarget >,
72+ val targetServers : List <TargetCrate >,
7573 val service : ShapeId ,
7674 val runtimeConfig : RuntimeConfig ,
7775) {
7876 companion object {
7977 fun fromNode (node : ObjectNode ): FuzzSettings {
80- val targetCrates = node.expectArrayMember(" targetCrates" ).map { FuzzTarget .fromNode(it.expectObjectNode()) }
78+ val targetCrates =
79+ node.expectArrayMember(" targetCrates" )
80+ .map { TargetCrate .fromNode(it.expectObjectNode()) }
8181 val service = ShapeId .fromNode(node.expectStringMember(" service" ))
8282 val runtimeConfig = RuntimeConfig .fromNode(node.getObjectMember(" runtimeConfig" ))
8383 return FuzzSettings (targetCrates, service, runtimeConfig)
8484 }
8585 }
8686}
8787
88+ /* *
89+ * Build plugin for generating a fuzz harness and lexicon from a smithy model and a set of smithy-rs versions
90+ *
91+ * This is used by `aws-smithy-fuzz` which contains most of the usage docs
92+ */
8893class FuzzHarnessBuildPlugin : SmithyBuildPlugin {
8994 override fun getName (): String = " fuzz-harness"
9095
@@ -95,10 +100,11 @@ class FuzzHarnessBuildPlugin : SmithyBuildPlugin {
95100 context.model.let (OperationNormalizer ::transform)
96101 .let (AttachValidationExceptionToConstrainedOperationInputsInAllowList ::transform)
97102 val targets =
98- fuzzSettings.targetCratePath.map { target ->
99- val target = createFuzzTarget(target, context.fileManifest, fuzzSettings, model)
100- FuzzTargetGenerator (target).generateFuzzTarget()
101- target
103+ fuzzSettings.targetServers.map { target ->
104+ val targetContext = createFuzzTarget(target, context.fileManifest, fuzzSettings, model)
105+ println (" Creating a fuzz targret for $targetContext " )
106+ FuzzTargetGenerator (targetContext).generateFuzzTarget()
107+ targetContext
102108 }
103109
104110 println (" creating the driver..." )
@@ -110,21 +116,9 @@ class FuzzHarnessBuildPlugin : SmithyBuildPlugin {
110116 }
111117}
112118
113- fun driverSettings (
114- service : ShapeId ,
115- runtimeConfig : RuntimeConfig ,
116- ) = CoreRustSettings (
117- service,
118- moduleVersion = " 0.1.0" ,
119- moduleName = " fuzz-driver" ,
120- moduleAuthors = listOf (),
121- codegenConfig = CoreCodegenConfig (),
122- license = null ,
123- runtimeConfig = runtimeConfig,
124- moduleDescription = null ,
125- moduleRepository = null ,
126- )
127-
119+ /* *
120+ * Generate a corpus of words used within the model to see the dictionary
121+ */
128122fun corpus (
129123 model : Model ,
130124 fuzzSettings : FuzzSettings ,
@@ -139,6 +133,7 @@ fun corpus(
139133 println (" base64 decoding first (v2)" )
140134 Base64 .getDecoder().decode(testCase.body.orNull())?.map { NumberNode .from(it.toUByte().toInt()) }
141135 }
136+
142137 else -> testCase.body.orNull()?.chars()?.toList()?.map { c -> NumberNode .from(c) }
143138 } ? : listOf ()
144139 out .withValue(
@@ -210,58 +205,8 @@ fun getTraitBasedNames(shape: Shape): List<String> {
210205 )
211206}
212207
213- fun createFuzzTarget (
214- target : FuzzTarget ,
215- baseManifest : FileManifest ,
216- fuzzSettings : FuzzSettings ,
217- model : Model ,
218- ): FuzzTargetContext {
219- val newManifest = FileManifest .create(baseManifest.resolvePath(Path .of(target.name)))
220- val codegenConfig = CoreCodegenConfig ()
221- val symbolProvider =
222- SymbolVisitor (
223- rustSettings(fuzzSettings, target),
224- model,
225- model.expectShape(fuzzSettings.service, ServiceShape ::class .java),
226- RustSymbolProviderConfig (
227- fuzzSettings.runtimeConfig,
228- renameExceptions = false ,
229- NullableIndex .CheckMode .SERVER ,
230- ServerModuleProvider ,
231- ),
232- ).let { PublicImportSymbolProvider (it, " rust_server_codegen" ) }
233- val crate =
234- RustCrate (
235- newManifest,
236- symbolProvider,
237- codegenConfig,
238- DocProvider (),
239- )
240- return FuzzTargetContext (
241- target = target,
242- fuzzSettings = fuzzSettings,
243- rustCrate = crate,
244- model = model,
245- manifest = newManifest,
246- symbolProvider = symbolProvider,
247- )
248- }
249-
250- class DocProvider : ModuleDocProvider {
208+ class NoOpDocProvider : ModuleDocProvider {
251209 override fun docsWriter (module : RustModule .LeafModule ): Writable ? {
252210 return null
253211 }
254212}
255-
256- class PublicCrateSymbolProvider (private val crateName : String , private val base : RustSymbolProvider ) :
257- WrappingSymbolProvider (base) {
258- override fun toSymbol (shape : Shape ): Symbol {
259- val base = base.toSymbol(shape)
260- return base.mapRustType { ty ->
261- when (ty) {
262- is RustType .Opaque -> RustType .Opaque (ty.name, ty.namespace?.replace(" crate" , crateName))
263- else -> ty
264- }
265- }
266- }
267- }
0 commit comments