@Test
    void assertWriteTraceFileFromScratchWorks() throws IOException, URISyntaxException {
        /**
         * Building TraceMetadata - this builder uses setTimestampAsNow, but you can also use a different
         * builder constructor to specify a custom timestamp.
         * The required fields are id, version, type, timestamp.
         */

        String id = "software.amazon.awssdk.services:snowball:2.10.79";
        String version = "2.10.79";
        String type = "Java";
        String typeVersion = "1.8";
        String homepage = "https://github.com/aws/aws-sdk-java-v2/";
        TraceMetadata traceMetadata = TraceMetadata.builder()
                .id(id)
                .version(version)
                .type(type)
                .setTimestampAsNow()
                .homepage(homepage)
                .typeVersion(typeVersion)
                .build();

        /**
         * Building Definitions - this example uses addTag and addType to add individual key value pairs.
         * There's another builder constructor that allows you to add the entire tags/types Map<String,String> without
         * having to add them individually.
         */
        ArtifactDefinitions artifactDefinitions = ArtifactDefinitions.builder()
                .addTag("service", "Service client")
                .addTag("request", "AWS SDK request type")
                .addTag("requestBuilder", "AWS SDK request builder")
                .addType("TYPE", "Class, interface (including annotation type), or enum declaration")
                .build();

        /**
         * Building TraceFile - build the trace file by passing the different objects to the builder
         * You can either construct the shapes map yourself, and add it to TraceFile, or you can add each shape
         * individually as shown below.
         * SmithyTrace is a constant in my code set to 1.0 for this version, so you don't have to worry about
         * setting it.
         */
        TraceFile.Builder traceFileBuilder = TraceFile.builder()
                .metadata(traceMetadata)
                .definitions(artifactDefinitions);

        //adding one ShapeLink to TraceFile
        type = "TYPE";
        id = "software.amazon.awssdk.services.snowball.SnowballClient";
        traceFileBuilder.addShapeLink("com.amazonaws.snowball#Snowball",
                ShapeLink.builder()
                        .type(type)
                        .id(id)
                        .addTag("service")
                        .build());

        //adding multiple ShapeLinks for the same ShapeId; can also add a List<ShapeLink>
        type = "TYPE";
        id = "software.amazon.awssdk.services.snowball.model.ListClusterJobsRequest$Builder";
        traceFileBuilder.addShapeLink("com.amazonaws.snowball#ListClustersRequest",
                ShapeLink.builder()
                        .type(type)
                        .id(id)
                        .addTag("requestBuilder")
                        .build());
        type = "TYPE";
        id = "software.amazon.awssdk.services.snowball.model.ListClusterJobsRequest";
        traceFileBuilder.addShapeLink("com.amazonaws.snowball#ListClustersRequest",
                ShapeLink.builder()
                        .type(type)
                        .id(id)
                        .addTag("request")
                        .build());

        //finally, build the TraceFile
        TraceFile traceFile = traceFileBuilder.build();

        /**
         * After creating a TraceFile, you may want to validate it. You can validate whether all your TraceFile
         * matches your model by checking if all the ShapeIds in a model file are in the TraceFile and all the
         * ShapeIds in a model file are in the TraceFile. This line is commented out here because there is no
         * Smithy model for this TraceFile, so it cannot be validated against a model. See validateModel tests
         * below for complete use cases.
         */
        //traceFile.validateModel(assembleModelTestHelper(("Your model resource path here");

        //Then write the TraceFile, just specify path/filename string.
        String filename = "trace-file-output.json";
        MockManifest manifest = writeTraceFileTestHelper(traceFile, filename);

        /**
         * Then parse the trace file, specify the files URI for parsing
         * Parsing fills all required fields and checks that they're filled
         */

        TraceFile traceFile2 = parseTraceFileFromManifest(manifest, filename);

        //few assorted checks
        assertThat(traceFile2.getMetadata().getId(), equalTo("software.amazon.awssdk.services:snowball:2.10.79"));
        assertThat(traceFile2.getArtifactDefinitions().get().getTags().keySet(),
                containsInAnyOrder("service",
                        "request",
                        "requestBuilder"));
        assertThat(traceFile2.getShapes().get(ShapeId.from("com.amazonaws.snowball#Snowball")).get(0).getType(),
                equalTo("TYPE"));
        assertThat(traceFile2.getSmithyTrace(), equalTo("1.0"));
    }
Correct TraceFile use tests
Test creating, parsing, validating and writing a TraceFile from scratch.
Test parse and write functionality combined on a correct trace file
Test parse and write functionality with nodes with single children instead of arrays of children
Test parse and write functionality combined on a correct trace file without the optional definitions section
smithy-codegen-core/src/test/java/software/amazon/smithy/codegen/core/trace/TraceFileTest.java