Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 11 additions & 4 deletions recorder/recorder.go
Original file line number Diff line number Diff line change
Expand Up @@ -563,16 +563,23 @@ func (rec *Recorder) Stop() error {
_, err := os.Stat(cassetteFile)
cassetteExists := !os.IsNotExist(err)

// Only save if there are interactions to save
hasInteractions := len(rec.cassette.Interactions) > 0

// Nothing to do for ModeReplayOnly and ModePassthrough here
switch {
case rec.mode == ModeRecordOnly || rec.mode == ModeReplayWithNewEpisodes:
if err := rec.persistCassette(); err != nil {
return err
if hasInteractions {
if err := rec.persistCassette(); err != nil {
return err
}
}

case rec.mode == ModeRecordOnce && !cassetteExists:
if err := rec.persistCassette(); err != nil {
return err
if hasInteractions {
if err := rec.persistCassette(); err != nil {
return err
}
}
}

Expand Down
124 changes: 124 additions & 0 deletions recorder/recorder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1271,3 +1271,127 @@ func TestDiscardInteractionsOnSave(t *testing.T) {
t.Fatalf("expected %d interactions, got %d", wantInteractions, gotInteractions)
}
}

func TestLazyFileCreation(t *testing.T) {
// Test that cassette files are only created when there are interactions to save

t.Run("ModeRecordOnly - no file created without interactions", func(t *testing.T) {
cassPath, err := newCassettePath("test_lazy_record_only")
if err != nil {
t.Fatal(err)
}

opts := []recorder.Option{
recorder.WithMode(recorder.ModeRecordOnly),
}
rec, err := recorder.New(cassPath, opts...)
if err != nil {
t.Fatal(err)
}

// Stop without making any requests
if err := rec.Stop(); err != nil {
t.Fatal(err)
}

// Verify file was NOT created
if _, err := cassette.Load(cassPath); !errors.Is(err, os.ErrNotExist) {
t.Fatal("expected cassette file to not exist when no interactions were recorded")
}
})

t.Run("ModeRecordOnce - no file created without interactions", func(t *testing.T) {
cassPath, err := newCassettePath("test_lazy_record_once")
if err != nil {
t.Fatal(err)
}

rec, err := recorder.New(cassPath)
if err != nil {
t.Fatal(err)
}

// Stop without making any requests
if err := rec.Stop(); err != nil {
t.Fatal(err)
}

// Verify file was NOT created
if _, err := cassette.Load(cassPath); !errors.Is(err, os.ErrNotExist) {
t.Fatal("expected cassette file to not exist when no interactions were recorded")
}
})

t.Run("ModeReplayWithNewEpisodes - no file created without interactions", func(t *testing.T) {
cassPath, err := newCassettePath("test_lazy_replay_with_new")
if err != nil {
t.Fatal(err)
}

opts := []recorder.Option{
recorder.WithMode(recorder.ModeReplayWithNewEpisodes),
}
rec, err := recorder.New(cassPath, opts...)
if err != nil {
t.Fatal(err)
}

// Stop without making any requests
if err := rec.Stop(); err != nil {
t.Fatal(err)
}

// Verify file was NOT created
if _, err := cassette.Load(cassPath); !errors.Is(err, os.ErrNotExist) {
t.Fatal("expected cassette file to not exist when no interactions were recorded")
}
})

t.Run("ModeRecordOnly - file created with interactions", func(t *testing.T) {
server := newEchoHttpServer()
defer server.Close()

cassPath, err := newCassettePath("test_lazy_with_interactions")
if err != nil {
t.Fatal(err)
}

opts := []recorder.Option{
recorder.WithMode(recorder.ModeRecordOnly),
}
rec, err := recorder.New(cassPath, opts...)
if err != nil {
t.Fatal(err)
}

// Make a request to create an interaction
client := rec.GetDefaultClient()
tc := testCase{
method: http.MethodGet,
wantBody: "GET go-vcr\n",
wantStatus: http.StatusOK,
wantContentLength: 11,
path: "/api/v1/foo",
}

ctx := context.Background()
if err := tc.run(ctx, client, server.URL); err != nil {
t.Fatal(err)
}

// Stop recorder
if err := rec.Stop(); err != nil {
t.Fatal(err)
}

// Verify file WAS created
c, err := cassette.Load(cassPath)
if err != nil {
t.Fatalf("expected cassette file to exist when interactions were recorded: %v", err)
}

if len(c.Interactions) != 1 {
t.Fatalf("expected 1 interaction, got %d", len(c.Interactions))
}
})
}
Loading