@@ -7,6 +7,7 @@ package v3
77
88import (
99 "net/http"
10+ "strconv"
1011 "testing"
1112
1213 "github.com/Azure/azure-sdk-for-go/sdk/azcore"
@@ -46,9 +47,14 @@ func NewTestRecorder(
4647 return nil , eris .Wrapf (err , "checking existence of cassette %s" , cassetteName )
4748 }
4849
50+ var cas * cassette.Cassette
4951 // Work out whether we are recording or replaying
5052 if cassetteExists {
5153 opts .Mode = recorder .ModeReplayOnly
54+ cas , err = cassette .Load (opts .CassetteName )
55+ if err != nil {
56+ return nil , eris .Wrapf (err , "loading cassette %s" , opts .CassetteName )
57+ }
5258 } else {
5359 opts .Mode = recorder .ModeRecordOnly
5460 }
@@ -78,6 +84,7 @@ func NewTestRecorder(
7884 cfg .AzureAuthorityHost = asocloud .DefaultAADAuthorityHost
7985 }
8086
87+ interactionCache := make (map [string ]string )
8188 // check body as well as URL/Method (copied from go-vcr documentation)
8289 r .SetMatcher (func (r * http.Request , i cassette.Request ) bool {
8390 if ! cassette .DefaultMatcher (r , i ) {
@@ -86,6 +93,31 @@ func NewTestRecorder(
8693
8794 // verify custom request count header matches, if present
8895 if header := r .Header .Get (CountHeader ); header != "" {
96+ reqCount , err := strconv .Atoi (header )
97+ if err != nil {
98+ log .Info ("Request count header parse error" , CountHeader , header )
99+ }
100+
101+ // If we've already seen 20 of this request, skip ahead to the end of the interaction to save replay time
102+ if reqCount > 20 {
103+ cachedFinalInteraction , ok := interactionCache [r .Method + " " + r .URL .String ()]
104+ if ok {
105+ header = cachedFinalInteraction
106+ } else {
107+ // Find the last interaction for this request
108+ for _ , interaction := range cas .Interactions {
109+ if ! cassette .DefaultMatcher (r , interaction .Request ) {
110+ continue
111+ }
112+ // We could parse the header and perform an integer comparison here to find the max,
113+ // but we don't need to because the interactions are stored in-order in the cassette so the
114+ // last interaction we find for this method+url will be the one with the highest count.
115+ header = interaction .Request .Headers .Get (CountHeader )
116+ interactionCache [r .Method + " " + r .URL .String ()] = header
117+ }
118+ }
119+ }
120+
89121 interactionHeader := i .Headers .Get (CountHeader )
90122 if header != interactionHeader {
91123 log .Info ("Request count header mismatch" , CountHeader , header , "interaction" , interactionHeader )
0 commit comments