Adds fuzz target for oss-fuzz integration
diff --git a/lib/go/test/fuzz/fuzz.go b/lib/go/test/fuzz/fuzz.go
new file mode 100644
index 0000000..388524c
--- /dev/null
+++ b/lib/go/test/fuzz/fuzz.go
@@ -0,0 +1,143 @@
+// +build gofuzz
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package fuzz
+
+import (
+	"context"
+	"fmt"
+	"shared"
+	"strconv"
+	"tutorial"
+
+	"github.com/apache/thrift/lib/go/thrift"
+)
+
+const nbFuzzedProtocols = 2
+
+func fuzzChooseProtocol(d byte, t thrift.TTransport) thrift.TProtocol {
+	switch d % nbFuzzedProtocols {
+	default:
+		fallthrough
+	case 0:
+		return thrift.NewTBinaryProtocolFactoryConf(nil).GetProtocol(t)
+	case 1:
+		return thrift.NewTCompactProtocolFactoryConf(nil).GetProtocol(t)
+	}
+}
+
+func Fuzz(data []byte) int {
+	if len(data) < 2 {
+		return 0
+	}
+	inputTransport := thrift.NewTMemoryBuffer()
+	inputTransport.Buffer.Write(data[2:])
+	outputTransport := thrift.NewTMemoryBuffer()
+	outputProtocol := fuzzChooseProtocol(data[0], outputTransport)
+	inputProtocol := fuzzChooseProtocol(data[1], inputTransport)
+	ctx := thrift.SetResponseHelper(
+		context.Background(),
+		thrift.TResponseHelper{
+			THeaderResponseHelper: thrift.NewTHeaderResponseHelper(outputProtocol),
+		},
+	)
+	handler := NewCalculatorHandler()
+	processor := tutorial.NewCalculatorProcessor(handler)
+	ok := true
+	var err error
+	for ok {
+		ok, err = processor.Process(ctx, inputProtocol, outputProtocol)
+		if err != nil {
+			// Handle parse error
+			return 0
+		}
+		res := make([]byte, 1024)
+		n, err := outputTransport.Buffer.Read(res)
+		fmt.Printf("lol %d %s %v\n", n, err, res)
+	}
+	return 1
+}
+
+type CalculatorHandler struct {
+	log map[int]*shared.SharedStruct
+}
+
+func NewCalculatorHandler() *CalculatorHandler {
+	return &CalculatorHandler{log: make(map[int]*shared.SharedStruct)}
+}
+
+func (p *CalculatorHandler) Ping(ctx context.Context) (err error) {
+	fmt.Print("ping()\n")
+	return nil
+}
+
+func (p *CalculatorHandler) Add(ctx context.Context, num1 int32, num2 int32) (retval17 int32, err error) {
+	fmt.Print("add(", num1, ",", num2, ")\n")
+	return num1 + num2, nil
+}
+
+func (p *CalculatorHandler) Calculate(ctx context.Context, logid int32, w *tutorial.Work) (val int32, err error) {
+	fmt.Print("calculate(", logid, ", {", w.Op, ",", w.Num1, ",", w.Num2, "})\n")
+	switch w.Op {
+	case tutorial.Operation_ADD:
+		val = w.Num1 + w.Num2
+		break
+	case tutorial.Operation_SUBTRACT:
+		val = w.Num1 - w.Num2
+		break
+	case tutorial.Operation_MULTIPLY:
+		val = w.Num1 * w.Num2
+		break
+	case tutorial.Operation_DIVIDE:
+		if w.Num2 == 0 {
+			ouch := tutorial.NewInvalidOperation()
+			ouch.WhatOp = int32(w.Op)
+			ouch.Why = "Cannot divide by 0"
+			err = ouch
+			return
+		}
+		val = w.Num1 / w.Num2
+		break
+	default:
+		ouch := tutorial.NewInvalidOperation()
+		ouch.WhatOp = int32(w.Op)
+		ouch.Why = "Unknown operation"
+		err = ouch
+		return
+	}
+	entry := shared.NewSharedStruct()
+	entry.Key = logid
+	entry.Value = strconv.Itoa(int(val))
+	k := int(logid)
+	p.log[k] = entry
+	return val, err
+}
+
+func (p *CalculatorHandler) GetStruct(ctx context.Context, key int32) (*shared.SharedStruct, error) {
+	fmt.Print("getStruct(", key, ")\n")
+	v, _ := p.log[int(key)]
+	return v, nil
+}
+
+func (p *CalculatorHandler) Zip(ctx context.Context) (err error) {
+	fmt.Print("zip()\n")
+	return nil
+}