Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/master'
Browse files Browse the repository at this point in the history
  • Loading branch information
pkskpro committed Jan 4, 2025
2 parents 086a0d9 + b888b0a commit 759170e
Show file tree
Hide file tree
Showing 6 changed files with 123 additions and 19 deletions.
12 changes: 11 additions & 1 deletion js/modules/k6/browser/common/browser.go
Original file line number Diff line number Diff line change
Expand Up @@ -493,12 +493,22 @@ func (b *Browser) newPageInContext(id cdp.BrowserContextID) (*Page, error) {
page = b.pages[tid]
b.pagesMu.RUnlock()
case <-ctx.Done():
b.logger.Debugf("Browser:newPageInContext:<-ctx.Done", "tid:%v bctxid:%v err:%v", tid, id, ctx.Err())
}

if err = ctx.Err(); err != nil {
err = &k6ext.UserFriendlyError{
Err: ctx.Err(),
Timeout: b.browserOpts.Timeout,
}
b.logger.Debugf("Browser:newPageInContext:<-ctx.Done", "tid:%v bctxid:%v err:%v", tid, id, err)
}

if err == nil && page == nil {
err = &k6ext.UserFriendlyError{
Err: errors.New("can't fetch the page for unknown reason"),
}
}

return page, err
}

Expand Down
13 changes: 1 addition & 12 deletions js/modules/k6/browser/common/browser_context.go
Original file line number Diff line number Diff line change
Expand Up @@ -262,18 +262,7 @@ func (b *BrowserContext) NewPage() (*Page, error) {
return nil, err
}

var (
bctxid cdp.BrowserContextID
ptid target.ID
)
if b != nil {
bctxid = b.id
}
if p != nil {
ptid = p.targetID
}
b.logger.Debugf("BrowserContext:NewPage:return", "bctxid:%v ptid:%s", bctxid, ptid)

b.logger.Debugf("BrowserContext:NewPage:return", "bctxid:%v ptid:%s", b.id, p.targetID)
return p, nil
}

Expand Down
63 changes: 61 additions & 2 deletions js/modules/k6/browser/common/http.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,30 @@ import (
k6modules "go.k6.io/k6/js/modules"
)

// These ResourceTypes are duplicates of CDP's network.ResourceType. We want to work
// with our version of ResourceType to catch any breaking changes early.
const (
ResourceTypeDocument string = "Document"
ResourceTypeStylesheet string = "Stylesheet"
ResourceTypeImage string = "Image"
ResourceTypeMedia string = "Media"
ResourceTypeFont string = "Font"
ResourceTypeScript string = "Script"
ResourceTypeTextTrack string = "TextTrack"
ResourceTypeXHR string = "XHR"
ResourceTypeFetch string = "Fetch"
ResourceTypePrefetch string = "Prefetch"
ResourceTypeEventSource string = "EventSource"
ResourceTypeWebSocket string = "WebSocket"
ResourceTypeManifest string = "Manifest"
ResourceTypeSignedExchange string = "SignedExchange"
ResourceTypePing string = "Ping"
ResourceTypeCSPViolationReport string = "CSPViolationReport"
ResourceTypePreflight string = "Preflight"
ResourceTypeOther string = "Other"
ResourceTypeUnknown string = "Unknown"
)

// HTTPHeader is a single HTTP header.
type HTTPHeader struct {
Name string `json:"name"`
Expand Down Expand Up @@ -88,7 +112,7 @@ type NewRequestParams struct {
}

// NewRequest creates a new HTTP request.
func NewRequest(ctx context.Context, rp NewRequestParams) (*Request, error) {
func NewRequest(ctx context.Context, logger *log.Logger, rp NewRequestParams) (*Request, error) {
ev := rp.event

documentID := cdp.LoaderID("")
Expand Down Expand Up @@ -129,7 +153,7 @@ func NewRequest(ctx context.Context, rp NewRequestParams) (*Request, error) {
requestID: ev.RequestID,
method: ev.Request.Method,
postDataEntries: pd,
resourceType: ev.Type.String(),
resourceType: validateResourceType(logger, ev.Type.String()),
isNavigationRequest: isNavigationRequest,
allowInterception: rp.allowInterception,
interceptionID: rp.interceptionID,
Expand All @@ -150,6 +174,41 @@ func NewRequest(ctx context.Context, rp NewRequestParams) (*Request, error) {
return &r, nil
}

// validateResourceType will validate network.ResourceType string values against our own
// ResourceType string values.
// - If a new network.ResourceType is added, this will log a warn and return
// ResourceTypeUnknown.
// - If an existing network.ResourceType is amended, this will log a warn and return
// ResourceTypeUnknown.
// - If a network.ResourceType is deleted then we will get a compilation error.
func validateResourceType(logger *log.Logger, t string) string {
switch t {
case ResourceTypeDocument:
case ResourceTypeStylesheet:
case ResourceTypeImage:
case ResourceTypeMedia:
case ResourceTypeFont:
case ResourceTypeScript:
case ResourceTypeTextTrack:
case ResourceTypeXHR:
case ResourceTypeFetch:
case ResourceTypePrefetch:
case ResourceTypeEventSource:
case ResourceTypeWebSocket:
case ResourceTypeManifest:
case ResourceTypeSignedExchange:
case ResourceTypePing:
case ResourceTypeCSPViolationReport:
case ResourceTypePreflight:
case ResourceTypeOther:
default:
t = ResourceTypeUnknown
logger.Warnf("http:resourceType", "unknown network.ResourceType %q detected", t)
}

return t
}

func (r *Request) getFrame() *Frame {
return r.frame
}
Expand Down
47 changes: 45 additions & 2 deletions js/modules/k6/browser/common/http_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package common

import (
"strings"
"testing"
"time"

Expand All @@ -10,6 +11,7 @@ import (
"github.com/stretchr/testify/require"

"go.k6.io/k6/js/modules/k6/browser/k6ext/k6test"
"go.k6.io/k6/js/modules/k6/browser/log"
)

func TestRequest(t *testing.T) {
Expand All @@ -30,7 +32,7 @@ func TestRequest(t *testing.T) {
WallTime: &wt,
}
vu := k6test.NewVU(t)
req, err := NewRequest(vu.Context(), NewRequestParams{
req, err := NewRequest(vu.Context(), log.NewNullLogger(), NewRequestParams{
event: evt,
interceptionID: "intercept",
})
Expand All @@ -51,7 +53,7 @@ func TestRequest(t *testing.T) {
WallTime: &wt,
}
vu := k6test.NewVU(t)
req, err := NewRequest(vu.Context(), NewRequestParams{
req, err := NewRequest(vu.Context(), log.NewNullLogger(), NewRequestParams{
event: evt,
interceptionID: "intercept",
})
Expand Down Expand Up @@ -124,3 +126,44 @@ func TestResponse(t *testing.T) {
assert.Equal(t, "value", got)
})
}

func TestValidateResourceType(t *testing.T) {
t.Parallel()

tests := []struct {
name string
input string
want string
}{
{name: ResourceTypeDocument, input: network.ResourceTypeDocument.String(), want: ResourceTypeDocument},
{name: ResourceTypeStylesheet, input: network.ResourceTypeStylesheet.String(), want: ResourceTypeStylesheet},
{name: ResourceTypeImage, input: network.ResourceTypeImage.String(), want: ResourceTypeImage},
{name: ResourceTypeMedia, input: network.ResourceTypeMedia.String(), want: ResourceTypeMedia},
{name: ResourceTypeFont, input: network.ResourceTypeFont.String(), want: ResourceTypeFont},
{name: ResourceTypeScript, input: network.ResourceTypeScript.String(), want: ResourceTypeScript},
{name: ResourceTypeTextTrack, input: network.ResourceTypeTextTrack.String(), want: ResourceTypeTextTrack},
{name: ResourceTypeXHR, input: network.ResourceTypeXHR.String(), want: ResourceTypeXHR},
{name: ResourceTypeFetch, input: network.ResourceTypeFetch.String(), want: ResourceTypeFetch},
{name: ResourceTypePrefetch, input: network.ResourceTypePrefetch.String(), want: ResourceTypePrefetch},
{name: ResourceTypeEventSource, input: network.ResourceTypeEventSource.String(), want: ResourceTypeEventSource},
{name: ResourceTypeWebSocket, input: network.ResourceTypeWebSocket.String(), want: ResourceTypeWebSocket},
{name: ResourceTypeManifest, input: network.ResourceTypeManifest.String(), want: ResourceTypeManifest},
{name: ResourceTypeSignedExchange, input: network.ResourceTypeSignedExchange.String(), want: ResourceTypeSignedExchange},
{name: ResourceTypePing, input: network.ResourceTypePing.String(), want: ResourceTypePing},
{name: ResourceTypeCSPViolationReport, input: network.ResourceTypeCSPViolationReport.String(), want: ResourceTypeCSPViolationReport},
{name: ResourceTypePreflight, input: network.ResourceTypePreflight.String(), want: ResourceTypePreflight},
{name: ResourceTypeOther, input: network.ResourceTypeOther.String(), want: ResourceTypeOther},
{name: "fake", input: "fake", want: ResourceTypeUnknown},
{name: "amended_existing", input: strings.ToLower(network.ResourceTypeOther.String()), want: ResourceTypeUnknown},
}

for _, tt := range tests {
tt := tt
t.Run(tt.name, func(t *testing.T) {
t.Parallel()

got := validateResourceType(log.NewNullLogger(), tt.input)
assert.Equal(t, got, tt.want)
})
}
}
5 changes: 4 additions & 1 deletion js/modules/k6/browser/common/network_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,7 @@ func (m *NetworkManager) emitRequestMetrics(req *Request) {
if state.Options.SystemTags.Has(k6metrics.TagURL) {
tags = handleURLTag(m.mi, req.URL(), req.method, tags)
}
tags = tags.With("resource_type", req.ResourceType())

k6metrics.PushIfNotDone(m.vu.Context(), state.Samples, k6metrics.ConnectedSamples{
Samples: []k6metrics.Sample{
Expand All @@ -192,6 +193,7 @@ func (m *NetworkManager) emitRequestMetrics(req *Request) {
})
}

//nolint:funlen
func (m *NetworkManager) emitResponseMetrics(resp *Response, req *Request) {
state := m.vu.State()

Expand Down Expand Up @@ -246,6 +248,7 @@ func (m *NetworkManager) emitResponseMetrics(resp *Response, req *Request) {
tags = tags.With("from_cache", strconv.FormatBool(fromCache))
tags = tags.With("from_prefetch_cache", strconv.FormatBool(fromPreCache))
tags = tags.With("from_service_worker", strconv.FormatBool(fromSvcWrk))
tags = tags.With("resource_type", req.ResourceType())

k6metrics.PushIfNotDone(m.vu.Context(), state.Samples, k6metrics.ConnectedSamples{
Samples: []k6metrics.Sample{
Expand Down Expand Up @@ -488,7 +491,7 @@ func (m *NetworkManager) onRequest(event *network.EventRequestWillBeSent, interc
event.Request.URL, event.Request.Method, event.Initiator.Type, event.FrameID)
}

req, err := NewRequest(m.ctx, NewRequestParams{
req, err := NewRequest(m.ctx, m.logger, NewRequestParams{
event: event,
frame: frame,
redirectChain: redirectChain,
Expand Down
2 changes: 1 addition & 1 deletion js/modules/k6/browser/common/network_manager_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,7 @@ func TestNetworkManagerEmitRequestResponseMetricsTimingSkew(t *testing.T) {
)
vu.ActivateVU()

req, err := NewRequest(vu.Context(), NewRequestParams{
req, err := NewRequest(vu.Context(), log.NewNullLogger(), NewRequestParams{
event: &network.EventRequestWillBeSent{
Request: &network.Request{},
Timestamp: (*cdp.MonotonicTime)(&tt.req.ts),
Expand Down

0 comments on commit 759170e

Please sign in to comment.