You are an expert in writing code in many different languages. Your goal is to perform code completion for the following code, keeping in mind the rest of the code and the file meta data.
    Metadata details:
    filename: middleware_add_test.go
    path of file: ./repos/aws-sdk-go-v2/service/internal/checksum
    
    the code of the file until where you have to start completion: //go:build go1.16
// +build go1.16

package checksum

import (
	"context"
	"fmt"
	"reflect"
	"testing"

	"github.com/aws/smithy-go/middleware"
	smithyhttp "github.com/aws/smithy-go/transport/http"
)

func TestAddInputMiddleware(t *testing.T) {
	cases := map[string]struct {
		options          InputMiddlewareOptions
		expectErr        string
		expectMiddleware []string
		expectInitialize *setupInputContext
		expectFinalize   *computeInputPayloadChecksum
	}{
		"with trailing checksum": {
			options: InputMiddlewareOptions{
				GetAlgorithm: func(interface{}) (string, bool) {
					return string(AlgorithmCRC32), true
				},
				EnableTrailingChecksum:           true,
				EnableComputeSHA256PayloadHash:   true,
				EnableDecodedContentLengthHeader: true,
			},
			expectMiddleware: []string{
				"test",
				"Initialize stack step",
				"AWSChecksum:SetupInputContext",
				"Serialize stack step",
				"Build stack step",
				"ComputeContentLength",
				"ComputePayloadHash",
				"Finalize stack step",
				"Retry",
				"addInputChecksumTrailer",
				"ResolveEndpointV2",
				"AWSChecksum:ComputeInputPayloadChecksum",
				"Signing",
				"Deserialize stack step",
			},
			expectInitialize: &setupInputContext{
				GetAlgorithm: func(interface{}) (string, bool) {
					return string(AlgorithmCRC32), true
				},
			},
			expectFinalize: &computeInputPayloadChecksum{
				EnableTrailingChecksum:           true,
				EnableComputePayloadHash:         true,
				EnableDecodedContentLengthHeader: true,
			},
		},
		"with checksum required": {
			options: InputMiddlewareOptions{
				GetAlgorithm: func(interface{}) (string, bool) {
					return string(AlgorithmCRC32), true
				},
				EnableTrailingChecksum: true,
				RequireChecksum:        true,
			},
			expectMiddleware: []string{
				"test",
				"Initialize stack step",
				"AWSChecksum:SetupInputContext",
				"Serialize stack step",
				"Build stack step",
				"ComputeContentLength",
				"ComputePayloadHash",
				"Finalize stack step",
				"Retry",
				"addInputChecksumTrailer",
				"ResolveEndpointV2",
				"AWSChecksum:ComputeInputPayloadChecksum",
				"Signing",
				"Deserialize stack step",
			},
			expectInitialize: &setupInputContext{
				GetAlgorithm: func(interface{}) (string, bool) {
					return string(AlgorithmCRC32), true
				},
			},
			expectFinalize: &computeInputPayloadChecksum{
				RequireChecksum:        true,
				EnableTrailingChecksum: true,
			},
		},
		"no trailing checksum": {
			options: InputMiddlewareOptions{
				GetAlgorithm: func(interface{}) (string, bool) {
					return string(AlgorithmCRC32), true
				},
			},
			expectMiddleware: []string{
				"test",
				"Initialize stack step",
				"AWSChecksum:SetupInputContext",
				"Serialize stack step",
				"Build stack step",
				"ComputeContentLength",
				"ComputePayloadHash",
				"Finalize stack step",
				"Retry",
				"ResolveEndpointV2",
				"AWSChecksum:ComputeInputPayloadChecksum",
				"Signing",
				"Deserialize stack step",
			},
			expectInitialize: &setupInputContext{
				GetAlgorithm: func(interface{}) (string, bool) {
					return string(AlgorithmCRC32), true
				},
			},
			expectFinalize: &computeInputPayloadChecksum{},
		},
	}

	for name, c := range cases {
		t.Run(name, func(t *testing.T) {
			stack := middleware.NewStack("test", smithyhttp.NewStackRequest)

			stack.Build.Add(nopBuildMiddleware("ComputeContentLength"), middleware.After)
			stack.Build.Add(nopBuildMiddleware("ContentChecksum"), middleware.After)
			stack.Build.Add(nopBuildMiddleware("ComputePayloadHash"), middleware.After)
			stack.Finalize.Add(nopFinalizeMiddleware("Retry"), middleware.After)
			stack.Finalize.Add(nopFinalizeMiddleware("ResolveEndpointV2"), middleware.After)
			stack.Finalize.Add(nopFinalizeMiddleware("Signing"), middleware.After)

			err := AddInputMiddleware(stack, c.options)
			if err != nil {
				t.Fatalf("expect no error, got %v", err)
			}

			if diff := cmpDiff(c.expectMiddleware, stack.List()); diff != "" {
				t.Fatalf("expect stack list match:\n%s", diff)
			}

			initializeMiddleware, ok := stack.Initialize.Get((*setupInputContext)(nil).ID())
			if e, a := (c.expectInitialize != nil), ok; e != a {
				t.Errorf("expect initialize middleware %t, got %t", e, a)
			}
			if c.expectInitialize != nil && ok {
				setupInput := init
    
func TestAddOutputMiddleware(t *testing.T) {
	cases := map[string]struct {
		options           OutputMiddlewareOptions
		expectErr         string
		expectMiddleware  []string
		expectInitialize  *setupOutputContext
		expectDeserialize *validateOutputPayloadChecksum
	}{
		"validate output": {
			options: OutputMiddlewareOptions{
				GetValidationMode: func(interface{}) (string, bool) {
					return "ENABLED", true
				},
				ValidationAlgorithms: []string{
					"crc32", "sha1", "abc123", "crc32c",
				},
				IgnoreMultipartValidation:     true,
				LogMultipartValidationSkipped: true,
				LogValidationSkipped:          true,
			},
			expectMiddleware: []string{
				"test",
				"Initialize stack step",
				"AWSChecksum:SetupOutputContext",
				"Serialize stack step",
				"Build stack step",
				"Finalize stack step",
				"Deserialize stack step",
				"AWSChecksum:ValidateOutputPayloadChecksum",
			},
			expectInitialize: &setupOutputContext{
				GetValidationMode: func(interface{}) (string, bool) {
					return "ENABLED", true
				},
			},
			expectDeserialize: &validateOutputPayloadChecksum{
				Algorithms: []Algorithm{
					AlgorithmCRC32, AlgorithmSHA1, AlgorithmCRC32C,
				},
				IgnoreMultipartValidation:     true,
				LogMultipartValidationSkipped: true,
				LogValidationSkipped:          true,
			},
		},
		"validate options off": {
			options: OutputMiddlewareOptions{
				GetValidationMode: func(interface{}) (string, bool) {
					return "ENABLED", true
				},
				ValidationAlgorithms: []string{
					"crc32", "sha1", "abc123", "crc32c",
				},
			},
			expectMiddleware: []string{
				"test",
				"Initialize stack step",
				"AWSChecksum:SetupOutputContext",
				"Serialize stack step",
				"Build stack step",
				"Finalize stack step",
				"Deserialize stack step",
				"AWSChecksum:ValidateOutputPayloadChecksum",
			},
			expectInitialize: &setupOutputContext{
				GetValidationMode: func(interface{}) (string, bool) {
					return "ENABLED", true
				},
			},
			expectDeserialize: &validateOutputPayloadChecksum{
				Algorithms: []Algorithm{
					AlgorithmCRC32, AlgorithmSHA1, AlgorithmCRC32C,
				},
			},
		},
	}

	for name, c := range cases {
		t.Run(name, func(t *testing.T) {
			stack := middleware.NewStack("test", smithyhttp.NewStackRequest)

			err := AddOutputMiddleware(stack, c.options)
			if err != nil {
				t.Fatalf("expect no error, got %v", err)
			}

			if diff := cmpDiff(c.expectMiddleware, stack.List()); diff != "" {
				t.Fatalf("expect stack list match:\n%s", diff)
			}

			initializeMiddleware, ok := stack.Initialize.Get((*setupOutputContext)(nil).ID())
			if e, a := (c.expectInitialize != nil), ok; e != a {
				t.Errorf("expect initialize middleware %t, got %t", e, a)
			}
			if c.expectInitialize != nil && ok {
				setupOutput := initializeMiddleware.(*setupOutputContext)
				if e, a := c.options.GetValidationMode != nil, setupOutput.GetValidationMode != nil; e != a {
					t.Fatalf("expect GetValidationMode %t, got %t", e, a)
				}
				expectMode, expectOK := c.options.GetValidationMode(nil)
				actualMode, actualOK := setupOutput.GetValidationMode(nil)
				if e, a := expectMode, actualMode; e != a {
					t.Errorf("expect %v mode, got %v", e, a)
				}
				if e, a := expectOK, actualOK; e != a {
					t.Errorf("expect %v mode present, got %v", e, a)
				}
			}

			deserializeMiddleware, ok := stack.Deserialize.Get((*validateOutputPayloadChecksum)(nil).ID())
			if e, a := (c.expectDeserialize != nil), ok; e != a {
				t.Errorf("expect deserialize middleware %t, got %t", e, a)
			}
			if c.expectDeserialize != nil && ok {
				validateOutput := deserializeMiddleware.(*validateOutputPayloadChecksum)
				if diff := cmpDiff(c.expectDeserialize.Algorithms, validateOutput.Algorithms); diff != "" {
					t.Errorf("expect algorithms match:\n%s", diff)
				}
				if e, a := c.expectDeserialize.IgnoreMultipartValidation, validateOutput.IgnoreMultipartValidation; e != a {
					t.Errorf("expect %v ignore multipart checksum, got %v", e, a)
				}
				if e, a := c.expectDeserialize.LogMultipartValidationSkipped, validateOutput.LogMultipartValidationSkipped; e != a {
					t.Errorf("expect %v log multipart skipped, got %v", e, a)
				}
				if e, a := c.expectDeserialize.LogValidationSkipped, validateOutput.LogValidationSkipped; e != a {
					t.Errorf("expect %v log validation skipped, got %v", e, a)
				}
			}
		})
	}
}