Categorygithub.com/feiyuw/simgo
modulepackage
0.1.1
Repository: https://github.com/feiyuw/simgo.git
Documentation: pkg.go.dev

# README

simgo is a simple service simulator for both client and server simulation. It can be used as a go unit test module, a web based test tool, or a test automation library(planned).

Build Status

Supported protocols:

protocolclient simulatorserver simulator
gRPC
HTTP××
Dubbo××

Used in go unit test

status: done

import (
	"time"
	"testing"

	"github.com/feiyuw/simgo/protocols"
	. "github.com/smartystreets/goconvey/convey"
)

func TestAsMockClient(t *testing.T) {
	Convey("test helloworld grpc service", t, func() {
		client, err := protocols.NewGrpcClient("127.0.0.1:3999", []string{"helloworld.proto"}, grpc.WithInsecure())
		So(err, ShouldBeNil)
		svcs, err := client.ListServices()
		So(err, ShouldBeNil)
		So(len(svcs), ShouldEqual, 1)
		So(svcs[0], ShouldEqual, "helloworld.Greeter")
		mtds, err := client.ListMethods("helloworld.Greeter")
		So(len(mtds), ShouldEqual, 1)
		So(mtds[0], ShouldEqual, "helloworld.Greeter.SayHello")
		out, err := client.InvokeRPC("helloworld.Greeter.SayHello", map[string]interface{}{"name": "you"})
		So(err, ShouldBeNil)
		So(out.(map[string]interface{})["message"], ShouldEqual, "Hello you")
	})
}

func TestAsMockServer(t *testing.T) {
	s, _ := protocols.NewGrpcServer(":4999", []string{"echo.proto"})
	s.SetMethodHandler("grpc.examples.echo.Echo.UnaryEcho", func(in *dynamic.Message, out *dynamic.Message, stream grpc.ServerStream) error {
		out.SetFieldByName("message", "hello")
		return nil
	})
	s.Start()
	defer s.Close()
	time.Sleep(time.Millisecond) // make sure server started

	Convey("use dynamic field in handler", t, func() {
		s.SetMethodHandler("grpc.examples.echo.Echo.UnaryEcho", func(in *dynamic.Message, out *dynamic.Message, stream grpc.ServerStream) error {
			out.SetFieldByName("message", in.GetFieldByName("message"))
			return nil
		})
		// your test code ...
	})

	Convey("use javascript handler", t, func() {
		s.SetMethodHandler("grpc.examples.echo.Echo.UnaryEcho", func(in *dynamic.Message, out *dynamic.Message, stream grpc.ServerStream) error {
			vm := otto.New()
			vm.Set("ctx", map[string]interface{}{
				"in":     in,
				"out":    out,
				"stream": stream,
			})
			vm.Run(`ctx.out.SetFieldByName("message", ctx.in.GetFieldByName("message"))`)
			return nil
		})
		// your test code ...
	})

	Convey("delay reply", t, func() {
		s.SetMethodHandler("grpc.examples.echo.Echo.UnaryEcho", func(in *dynamic.Message, out *dynamic.Message, stream grpc.ServerStream) error {
			time.Sleep(time.Second)
			out.SetFieldByName("message", "delay 1 sec")
			return nil
		})
		// your test code ...
	})

	Convey("streaming API", t, func() {
		s.SetMethodHandler("grpc.examples.echo.Echo.BidirectionalStreamingEcho", func(in *dynamic.Message, out *dynamic.Message, stream grpc.ServerStream) error {
			for {
				if err := stream.RecvMsg(in); err == io.EOF {
					break
				}
				out.SetFieldByName("message", in.GetFieldByName("message"))
				stream.SendMsg(out)
			}
			return nil
		})
		// your test code ...
	})
}

As a web based test tool

status: draft

simgo can be used as a web based RPC test tool. Download the latest release.

As a client simulator.

client

As a server simulator.

server

Handler examples

  1. static response

    type: raw

    content: {"message": "hello world"}

  2. dynamic response

    type: javascript

    content:

    	ctx.out.SetFieldByName("message", "hello " + ctx.in.GetFieldByName("message"))
    
  3. delay response

    type: javascript

    content:

    	ctx.Sleep(1) // 1 second
    	ctx.out.SetFieldByName("message", ctx.in.GetFieldByName("message"))
    
  4. streaming response

    type: javascript

    content:

    	ctx.stream.RecvMsg(ctx.in)  // read input stream
    	ctx.out.SetFieldByName("message", ctx.in.GetFieldByName("message"))
    	ctx.stream.SendMsg(ctx.out)  // send output stream
    
  5. error response

As a test automation library

status: planned

# Packages

No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author