// 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()...)

Since a real connection isn't necessary for replay, you can get a fake
one from the replayer instead of calling grpc.Dial:

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

# 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

Recorders and replayers have support for running callbacks before messages are
written to or 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.

The same is not true of streaming RPCs. The replayer matches streams only by method
name, since it has no other information at the time the stream is opened. Two streams
with the same method name that are started concurrently may replay in the wrong
order.

# 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"
