Skip to content

Commit

Permalink
update end-to-end test server to implement resource detection scenario
Browse files Browse the repository at this point in the history
  • Loading branch information
dashpole committed May 19, 2022
1 parent 55ba58d commit d5bfdbf
Show file tree
Hide file tree
Showing 9 changed files with 241 additions and 63 deletions.
5 changes: 5 additions & 0 deletions detectors/gcp/app_engine.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,8 @@ func (d *Detector) AppEngineServiceInstance() (string, error) {
}
return "", errEnvVarNotFound
}

// AppEngineAvailabilityZoneAndRegion returns the zone and region in which this program is running
func (d *Detector) AppEngineAvailabilityZoneAndRegion() (string, string, error) {
return d.GCEAvailabilityZoneAndRegion()
}
16 changes: 8 additions & 8 deletions detectors/gcp/faas.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,31 +40,31 @@ func (d *Detector) onCloudFunctions() bool {
return found
}

// FAASName returns the name of the cloud run or cloud functions service.
func (d *Detector) FAASName() (string, error) {
// FaaSName returns the name of the cloud run or cloud functions service.
func (d *Detector) FaaSName() (string, error) {
if name, found := d.os.LookupEnv(faasServiceEnv); found {
return name, nil
}
return "", errEnvVarNotFound
}

// FAASVersion returns the revision of the cloud run or cloud functions service
func (d *Detector) FAASVersion() (string, error) {
// FaaSVersion returns the revision of the cloud run or cloud functions service
func (d *Detector) FaaSVersion() (string, error) {
if version, found := d.os.LookupEnv(faasRevisionEnv); found {
return version, nil
}
return "", errEnvVarNotFound
}

// FAASVersion returns the instance id of the cloud run instance or cloud function
func (d *Detector) FAASInstanceID() (string, error) {
// FaaSID returns the instance id of the cloud run instance or cloud function
func (d *Detector) FaaSID() (string, error) {
return d.metadata.InstanceID()
}

// FAASCloudRegion detects region from the metadata server. It is in the
// FaaSCloudRegion detects region from the metadata server. It is in the
// format /projects/<project_number>/regions/<region>.
// https://cloud.google.com/run/docs/reference/container-contract#metadata-server
func (d *Detector) FAASCloudRegion() (string, error) {
func (d *Detector) FaaSCloudRegion() (string, error) {
region, err := d.metadata.Get(regionMetadataAttr)
if err != nil {
return "", err
Expand Down
32 changes: 16 additions & 16 deletions detectors/gcp/faas_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,78 +21,78 @@ import (
"github.com/stretchr/testify/assert"
)

func TestFAASName(t *testing.T) {
func TestFaaSName(t *testing.T) {
d := NewTestDetector(&FakeMetadataProvider{}, &FakeOSProvider{
Vars: map[string]string{
faasServiceEnv: "my-service",
},
})
name, err := d.FAASName()
name, err := d.FaaSName()
assert.NoError(t, err)
assert.Equal(t, name, "my-service")
}

func TestFAASNameErr(t *testing.T) {
func TestFaaSNameErr(t *testing.T) {
d := NewTestDetector(&FakeMetadataProvider{}, &FakeOSProvider{
Vars: map[string]string{},
})
name, err := d.FAASName()
name, err := d.FaaSName()
assert.Error(t, err)
assert.Equal(t, name, "")
}

func TestFAASVersion(t *testing.T) {
func TestFaaSVersion(t *testing.T) {
d := NewTestDetector(&FakeMetadataProvider{}, &FakeOSProvider{
Vars: map[string]string{
faasRevisionEnv: "version-123",
},
})
version, err := d.FAASVersion()
version, err := d.FaaSVersion()
assert.NoError(t, err)
assert.Equal(t, version, "version-123")
}

func TestFAASVersionErr(t *testing.T) {
func TestFaaSVersionErr(t *testing.T) {
d := NewTestDetector(&FakeMetadataProvider{}, &FakeOSProvider{
Vars: map[string]string{},
})
version, err := d.FAASVersion()
version, err := d.FaaSVersion()
assert.Error(t, err)
assert.Equal(t, version, "")
}

func TestFAASInstanceID(t *testing.T) {
func TestFaaSInstanceID(t *testing.T) {
d := NewTestDetector(&FakeMetadataProvider{
FakeInstanceID: "instance-id-123",
}, &FakeOSProvider{})
instance, err := d.FAASInstanceID()
instance, err := d.FaaSID()
assert.NoError(t, err)
assert.Equal(t, instance, "instance-id-123")
}

func TestFAASInstanceIDErr(t *testing.T) {
func TestFaaSInstanceIDErr(t *testing.T) {
d := NewTestDetector(&FakeMetadataProvider{
Err: fmt.Errorf("fake error"),
}, &FakeOSProvider{})
instance, err := d.FAASInstanceID()
instance, err := d.FaaSID()
assert.Error(t, err)
assert.Equal(t, instance, "")
}

func TestFAASCloudRegion(t *testing.T) {
func TestFaaSCloudRegion(t *testing.T) {
d := NewTestDetector(&FakeMetadataProvider{
Attributes: map[string]string{regionMetadataAttr: "/projects/123/regions/us-central1"},
}, &FakeOSProvider{})
instance, err := d.FAASCloudRegion()
instance, err := d.FaaSCloudRegion()
assert.NoError(t, err)
assert.Equal(t, instance, "us-central1")
}

func TestFAASCloudRegionErr(t *testing.T) {
func TestFaaSCloudRegionErr(t *testing.T) {
d := NewTestDetector(&FakeMetadataProvider{
Err: fmt.Errorf("fake error"),
}, &FakeOSProvider{})
instance, err := d.FAASCloudRegion()
instance, err := d.FaaSCloudRegion()
assert.Error(t, err)
assert.Equal(t, instance, "")
}
2 changes: 1 addition & 1 deletion detectors/gcp/go.mod
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
module go.opentelemetry.io/contrib/detectors/gcp
module github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp

go 1.17

Expand Down
1 change: 1 addition & 0 deletions e2e-test-server/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ WORKDIR /workspace/e2e-test-server/
# In-repo dependencies
COPY exporter/trace/ ../exporter/trace/
COPY internal/resourcemapping/ ../internal/resourcemapping
COPY detectors/gcp/ ../detectors/gcp/

# cache deps before copying source so that source changes don't invalidate our
# downloaded layer and we don't need to re-download as much.
Expand Down
81 changes: 71 additions & 10 deletions e2e-test-server/endtoendserver/scenarios.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,20 +19,20 @@ import (
"log"

"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/sdk/resource"
sdktrace "go.opentelemetry.io/otel/sdk/trace"
"go.opentelemetry.io/otel/trace"
"google.golang.org/genproto/googleapis/rpc/code"
)

var scenarioHandlers = map[string]scenarioHandler{
"/basicPropagator": (*Server).unimplementedHandler,
"/basicTrace": (*Server).basicTraceHandler,
"/complexTrace": (*Server).complexTraceHandler,
"/health": (*Server).healthHandler,
"/basicPropagator": &unimplementedHandler{},
"/basicTrace": &basicTraceHandler{},
"/complexTrace": &complexTraceHandler{},
"/detectResource": &detectResourceHandler{},
"/health": &healthHandler{},
}

type scenarioHandler func(*Server, context.Context, request, *sdktrace.TracerProvider) *response

type request struct {
scenario string
testID string
Expand All @@ -44,13 +44,26 @@ type response struct {
traceID trace.TraceID
}

type scenarioHandler interface {
handle(context.Context, request, *sdktrace.TracerProvider) *response
tracerProvider() (*sdktrace.TracerProvider, error)
}

// healthHandler returns an OK response without creating any traces.
func (s *Server) healthHandler(ctx context.Context, req request, tracerProvider *sdktrace.TracerProvider) *response {
type healthHandler struct{}

func (*healthHandler) handle(ctx context.Context, req request, tracerProvider *sdktrace.TracerProvider) *response {
return &response{statusCode: code.Code_OK}
}

func (*healthHandler) tracerProvider() (*sdktrace.TracerProvider, error) {
return newTraceProvider(resource.Empty())
}

// basicTraceHandler creates a basic trace and returns an OK response.
func (s *Server) basicTraceHandler(ctx context.Context, req request, tracerProvider *sdktrace.TracerProvider) *response {
type basicTraceHandler struct{}

func (*basicTraceHandler) handle(ctx context.Context, req request, tracerProvider *sdktrace.TracerProvider) *response {
if req.testID == "" {
log.Printf("request is missing required field 'testID'. request: %+v", req)
return &response{
Expand All @@ -67,8 +80,14 @@ func (s *Server) basicTraceHandler(ctx context.Context, req request, tracerProvi
return &response{statusCode: code.Code_OK, traceID: span.SpanContext().TraceID()}
}

func (*basicTraceHandler) tracerProvider() (*sdktrace.TracerProvider, error) {
return newTraceProvider(resource.Empty())
}

// complexTraceHandler creates a complex trace and returns an OK response.
func (s *Server) complexTraceHandler(ctx context.Context, req request, tracerProvider *sdktrace.TracerProvider) *response {
type complexTraceHandler struct{}

func (*complexTraceHandler) handle(ctx context.Context, req request, tracerProvider *sdktrace.TracerProvider) *response {
if req.testID == "" {
log.Printf("request is missing required field 'testID'. request: %+v", req)
return &response{
Expand Down Expand Up @@ -105,8 +124,50 @@ func (s *Server) complexTraceHandler(ctx context.Context, req request, tracerPro
return &response{statusCode: code.Code_OK, traceID: rootSpan.SpanContext().TraceID()}
}

func (*complexTraceHandler) tracerProvider() (*sdktrace.TracerProvider, error) {
return newTraceProvider(resource.Empty())
}

// detectResourceHandler creates a basic trace with resource info and returns an OK response.
type detectResourceHandler struct{}

func (*detectResourceHandler) handle(ctx context.Context, req request, tracerProvider *sdktrace.TracerProvider) *response {
if req.testID == "" {
log.Printf("request is missing required field 'testID'. request: %+v", req)
return &response{
statusCode: code.Code_INVALID_ARGUMENT,
data: []byte("request is missing required field 'testID'"),
}
}

tracer := tracerProvider.Tracer(instrumentingModuleName)
_, span := tracer.Start(ctx, "resourceDetectionTrace",
trace.WithAttributes(attribute.String(testIDKey, req.testID)))
span.End()

return &response{statusCode: code.Code_OK, traceID: span.SpanContext().TraceID()}
}

func (*detectResourceHandler) tracerProvider() (*sdktrace.TracerProvider, error) {
res, err := resource.New(context.Background(),
resource.WithDetectors(&testDetector{}),
resource.WithFromEnv(),
resource.WithTelemetrySDK(),
)
if err != nil {
return nil, err
}
return newTraceProvider(res)
}

// unimplementedHandler returns an UNIMPLEMENTED response without creating any traces.
func (s *Server) unimplementedHandler(ctx context.Context, req request, tracerProvider *sdktrace.TracerProvider) *response {
type unimplementedHandler struct{}

func (*unimplementedHandler) handle(ctx context.Context, req request, tracerProvider *sdktrace.TracerProvider) *response {
log.Printf("received unhandled scenario %q", req.scenario)
return &response{statusCode: code.Code_UNIMPLEMENTED}
}

func (*unimplementedHandler) tracerProvider() (*sdktrace.TracerProvider, error) {
return newTraceProvider(resource.Empty())
}
Loading

0 comments on commit d5bfdbf

Please sign in to comment.