// Copyright 2017 Google LLC
//
// Licensed 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 rpcreplay supports the capture and replay of gRPC calls. Its main goal is
to improve testing. Once you capture the calls of a test that runs against a real
service, you have an "automatic mock" that can be replayed against the same test,
yielding a unit test that is fast and flake-free.

This package is EXPERIMENTAL and subject to change without notice.


Recording

To record a sequence of gRPC calls to a file, create a Recorder and pass its
DialOptions to grpc.Dial:

    rec, err := rpcreplay.NewRecorder("service.replay", nil)
    if err != nil { ... }
    defer func() {
        if err := rec.Close(); err != nil { ... }
    }()
    conn, err := grpc.Dial(serverAddress, rec.DialOptions()...)

It is essential to close the Recorder when the interaction is finished.

There is also a NewRecorderWriter function for capturing to an arbitrary
io.Writer.


Replaying

Replaying a captured file looks almost identical: create a Replayer and use
its DialOptions. (Since we're reading the file and not writing it, we don't
have to be as careful about the error returned from Close).

    rep, err := rpcreplay.NewReplayer("service.replay")
    if err != nil { ... }
    defer rep.Close()
    conn, err := grpc.Dial(serverAddress, rep.DialOptions()...)


Initial State

A test might use random or time-sensitive values, for instance to create unique
resources for isolation from other tests. The test therefore has initial values, such
as the current time, or a random seed, that differ from run to run. You must record
this initial state and re-establish it on replay.

To record the initial state, serialize it into a []byte and pass it as the second
argument to NewRecorder:

   timeNow := time.Now()
   b, err := timeNow.MarshalBinary()
   if err != nil { ... }
   rec, err := rpcreplay.NewRecorder("service.replay", b)

On replay, get the bytes from Replayer.Initial:

   rep, err := rpcreplay.NewReplayer("service.replay")
   if err != nil { ... }
   defer rep.Close()
   err = timeNow.UnmarshalBinary(rep.Initial())
   if err != nil { ... }


Callbacks that modify what is saved and matched from the replay file

Recorders and replayers have support for running callbacks before messages are written/read
from the replay file. A Recorder has a BeforeFunc that can modify a request or response
before it is written to the replay file. The actual RPCs sent to the service during recording
remain unaltered; only what is saved in the replay file can be changed.A Replayer has a
BeforeFunc that can modify a request before it is sent for matching.

Example uses for these callbacks include customized logging, or scrubbing data
before RPCs are written to the replay file. If requests are modified by the callbacks during recording,
it is important to perform the same modifications to the requests when replaying, or RPC
matching on replay will fail.

A common way to analyze and modify the various messages is to use a type switch.

	// Assume these types implement proto.Message.
	type Greeting struct {
		line string
	}

	type Farewell struct {
		line string
	}

	func sayings(method string, msg proto.Message) error {
		switch m := msg.(type) {
		case Greeting:
			msg.line = "Hi!"
			return nil
		case Farewell:
			msg.line = "Bye bye!"
			return nil
		default:
			return fmt.Errorf("unknown message type")
		}
	}

Nondeterminism

A nondeterministic program may invoke RPCs in a different order each time
it is run. The order in which RPCs are called during recording may differ
from the order during replay.

The replayer matches incoming to recorded requests by method name and request
contents, so nondeterminism is only a concern for identical requests that result
in different responses. A nondeterministic program whose behavior differs
depending on the order of such RPCs probably has a race condition: since both the
recorded sequence of RPCs and the sequence during replay are valid orderings, the
program should behave the same under both.


Other Replayer Differences

Besides the differences in replay mentioned above, other differences may cause issues
for some programs. We list them here.

The Replayer delivers a response to an RPC immediately, without waiting for other
incoming RPCs. This can violate causality. For example, in a Pub/Sub program where
one goroutine publishes and another subscribes, during replay the Subscribe call may
finish before the Publish call begins.

For streaming RPCs, the Replayer delivers the result of Send and Recv calls in
the order they were recorded. No attempt is made to match message contents.

At present, this package does not record or replay stream headers and trailers, or
the result of the CloseSend method.
*/
package rpcreplay // import "cloud.google.com/go/rpcreplay"
