diff --git a/core/request_option.go b/core/request_option.go index 6899806..d4ecd72 100644 --- a/core/request_option.go +++ b/core/request_option.go @@ -56,8 +56,8 @@ func (r *RequestOptions) cloneHeader() http.Header { headers := r.HTTPHeader.Clone() headers.Set("X-Fern-Language", "Go") headers.Set("X-Fern-SDK-Name", "github.com/anduril/lattice-sdk-go/v3") - headers.Set("X-Fern-SDK-Version", "v3.0.0") - headers.Set("User-Agent", "github.com/anduril/lattice-sdk-go/3.0.0") + headers.Set("X-Fern-SDK-Version", "v3.1.0") + headers.Set("User-Agent", "github.com/anduril/lattice-sdk-go/3.1.0") return headers } diff --git a/entities/entities_test/entities_test.go b/entities/entities_test/entities_test.go new file mode 100644 index 0000000..6c5047c --- /dev/null +++ b/entities/entities_test/entities_test.go @@ -0,0 +1,316 @@ +// Code generated by Fern. DO NOT EDIT. + +package entities_test + +import ( + context "context" + fmt "fmt" + v3 "github.com/anduril/lattice-sdk-go/v3" + client "github.com/anduril/lattice-sdk-go/v3/client" + option "github.com/anduril/lattice-sdk-go/v3/option" + require "github.com/stretchr/testify/require" + gowiremock "github.com/wiremock/go-wiremock" + wiremocktestcontainersgo "github.com/wiremock/wiremock-testcontainers-go" + http "net/http" + os "os" + testing "testing" +) + +// TestMain sets up shared test fixtures for all tests in this package// Global test fixtures +var ( + WireMockContainer *wiremocktestcontainersgo.WireMockContainer + WireMockBaseURL string + WireMockClient *gowiremock.Client +) + +// TestMain sets up shared test fixtures for all tests in this package +func TestMain(m *testing.M) { + // Setup shared WireMock container + ctx := context.Background() + container, err := wiremocktestcontainersgo.RunContainerAndStopOnCleanup( + ctx, + &testing.T{}, + wiremocktestcontainersgo.WithImage("docker.io/wiremock/wiremock:3.9.1"), + ) + if err != nil { + fmt.Printf("Failed to start WireMock container: %v\n", err) + os.Exit(1) + } + + // Store global references + WireMockContainer = container + + // Try to get the base URL using the standard method first + baseURL, err := container.Endpoint(ctx, "") + if err == nil { + // Standard method worked (running outside DinD) + // This uses the mapped port (e.g., localhost:59553) + WireMockBaseURL = "http://" + baseURL + WireMockClient = container.Client + } else { + // Standard method failed, use internal IP fallback (DinD environment) + fmt.Printf("Standard endpoint resolution failed, using internal IP fallback: %v\n", err) + + inspect, err := container.Inspect(ctx) + if err != nil { + fmt.Printf("Failed to inspect WireMock container: %v\n", err) + os.Exit(1) + } + + // Find the IP address from the container's networks + var containerIP string + for _, network := range inspect.NetworkSettings.Networks { + if network.IPAddress != "" { + containerIP = network.IPAddress + break + } + } + + if containerIP == "" { + fmt.Printf("Failed to get WireMock container IP address\n") + os.Exit(1) + } + + // In DinD, use the internal port directly (8080 for WireMock HTTP) + // Don't use the mapped port since it doesn't exist in this environment + WireMockBaseURL = fmt.Sprintf("http://%s:8080", containerIP) + + // The container.Client was created with a bad URL, so we need a new one + WireMockClient = gowiremock.NewClient(WireMockBaseURL) + } + + fmt.Printf("WireMock available at: %s\n", WireMockBaseURL) + + // Run all tests + code := m.Run() + + // Cleanup + if WireMockContainer != nil { + WireMockContainer.Terminate(ctx) + } + + // Exit with the same code as the tests + os.Exit(code) +} + +func TestEntitiesPublishEntityWithWireMock( + t *testing.T, +) { + // wiremock client and server initialized in shared main_test.go + defer WireMockClient.Reset() + stub := gowiremock.Put(gowiremock.URLPathTemplate("/api/v1/entities")).WithBodyPattern(gowiremock.MatchesJsonSchema("{}", "V202012")).WillReturnResponse( + gowiremock.NewResponse().WithJSONBody( + map[string]interface{}{"entityId": "entityId", "description": "description", "isLive": true, "createdTime": "2024-01-15T09:30:00Z", "expiryTime": "2024-01-15T09:30:00Z", "noExpiry": true, "status": map[string]interface{}{"code": 1, "message": "message", "details": []interface{}{map[string]interface{}{}}}, "location": map[string]interface{}{"position": map[string]interface{}{"latitudeDegrees": 1.1, "longitudeDegrees": 1.1, "altitudeHaeMeters": 1.1, "altitudeAglMeters": 1.1, "altitudeAsfMeters": 1.1, "pressureDepthMeters": 1.1}, "velocityEnu": map[string]interface{}{"e": 1.1, "n": 1.1, "u": 1.1}, "speedMps": 1.1, "acceleration": map[string]interface{}{"e": 1.1, "n": 1.1, "u": 1.1}, "attitudeEnu": map[string]interface{}{"x": 1.1, "y": 1.1, "z": 1.1, "w": 1.1}}, "locationUncertainty": map[string]interface{}{"positionEnuCov": map[string]interface{}{"mxx": 1.1, "mxy": 1.1, "mxz": 1.1, "myy": 1.1, "myz": 1.1, "mzz": 1.1}, "velocityEnuCov": map[string]interface{}{"mxx": 1.1, "mxy": 1.1, "mxz": 1.1, "myy": 1.1, "myz": 1.1, "mzz": 1.1}, "positionErrorEllipse": map[string]interface{}{"probability": 1.1, "semiMajorAxisM": 1.1, "semiMinorAxisM": 1.1, "orientationD": 1.1}}, "geoShape": map[string]interface{}{"line": map[string]interface{}{"positions": []interface{}{map[string]interface{}{}}}, "polygon": map[string]interface{}{"rings": []interface{}{map[string]interface{}{}}, "isRectangle": true}, "ellipse": map[string]interface{}{"semiMajorAxisM": 1.1, "semiMinorAxisM": 1.1, "orientationD": 1.1, "heightM": 1.1}, "ellipsoid": map[string]interface{}{"forwardAxisM": 1.1, "sideAxisM": 1.1, "upAxisM": 1.1}}, "geoDetails": map[string]interface{}{"type": "GEO_TYPE_INVALID", "controlArea": map[string]interface{}{"type": "CONTROL_AREA_TYPE_INVALID"}, "acm": map[string]interface{}{"acmType": "ACM_DETAIL_TYPE_INVALID", "acmDescription": "acmDescription"}}, "aliases": map[string]interface{}{"alternateIds": []interface{}{map[string]interface{}{}}, "name": "name"}, "tracked": map[string]interface{}{"trackQualityWrapper": 1, "sensorHits": 1, "numberOfObjects": map[string]interface{}{"lowerBound": 1, "upperBound": 1}, "radarCrossSection": 1.1, "lastMeasurementTime": "2024-01-15T09:30:00Z"}, "correlation": map[string]interface{}{"primary": map[string]interface{}{"secondaryEntityIds": []interface{}{"secondaryEntityIds"}}, "secondary": map[string]interface{}{"primaryEntityId": "primaryEntityId"}, "membership": map[string]interface{}{"correlationSetId": "correlationSetId"}, "decorrelation": map[string]interface{}{"decorrelatedEntities": []interface{}{map[string]interface{}{}}}}, "milView": map[string]interface{}{"disposition": "DISPOSITION_UNKNOWN", "environment": "ENVIRONMENT_UNKNOWN", "nationality": "NATIONALITY_INVALID"}, "ontology": map[string]interface{}{"platformType": "platformType", "specificType": "specificType", "template": "TEMPLATE_INVALID"}, "sensors": map[string]interface{}{"sensors": []interface{}{map[string]interface{}{}}}, "payloads": map[string]interface{}{"payloadConfigurations": []interface{}{map[string]interface{}{}}}, "powerState": map[string]interface{}{"sourceIdToState": map[string]interface{}{"key": map[string]interface{}{}}}, "provenance": map[string]interface{}{"integrationName": "integrationName", "dataType": "dataType", "sourceId": "sourceId", "sourceUpdateTime": "2024-01-15T09:30:00Z", "sourceDescription": "sourceDescription"}, "overrides": map[string]interface{}{"override": []interface{}{map[string]interface{}{}}}, "indicators": map[string]interface{}{"simulated": true, "exercise": true, "emergency": true, "c2": true, "egressable": true, "starred": true}, "targetPriority": map[string]interface{}{"highValueTarget": map[string]interface{}{"isHighValueTarget": true, "targetPriority": 1, "targetMatches": []interface{}{map[string]interface{}{}}, "isHighPayoffTarget": true}, "threat": map[string]interface{}{"isThreat": true}}, "signal": map[string]interface{}{"bandwidthHz": 1.1, "signalToNoiseRatio": 1.1, "emitterNotations": []interface{}{map[string]interface{}{}}, "pulseWidthS": 1.1, "scanCharacteristics": map[string]interface{}{"scanType": "SCAN_TYPE_INVALID", "scanPeriodS": 1.1}}, "transponderCodes": map[string]interface{}{"mode1": 1, "mode2": 1, "mode3": 1, "mode4InterrogationResponse": "INTERROGATION_RESPONSE_INVALID", "mode5": map[string]interface{}{"mode5InterrogationResponse": "INTERROGATION_RESPONSE_INVALID", "mode5": 1, "mode5PlatformId": 1}, "modeS": map[string]interface{}{"id": "id", "address": 1}}, "dataClassification": map[string]interface{}{"default": map[string]interface{}{"level": "CLASSIFICATION_LEVELS_INVALID", "caveats": []interface{}{"caveats"}}, "fields": []interface{}{map[string]interface{}{}}}, "taskCatalog": map[string]interface{}{"taskDefinitions": []interface{}{map[string]interface{}{}}}, "media": map[string]interface{}{"media": []interface{}{map[string]interface{}{}}}, "relationships": map[string]interface{}{"relationships": []interface{}{map[string]interface{}{}}}, "visualDetails": map[string]interface{}{"rangeRings": map[string]interface{}{"minDistanceM": 1.1, "maxDistanceM": 1.1, "ringCount": 1}}, "dimensions": map[string]interface{}{"lengthM": 1.1}, "routeDetails": map[string]interface{}{"destinationName": "destinationName", "estimatedArrivalTime": "2024-01-15T09:30:00Z"}, "schedules": map[string]interface{}{"schedules": []interface{}{map[string]interface{}{}}}, "health": map[string]interface{}{"connectionStatus": "CONNECTION_STATUS_INVALID", "healthStatus": "HEALTH_STATUS_INVALID", "components": []interface{}{map[string]interface{}{}}, "updateTime": "2024-01-15T09:30:00Z", "activeAlerts": []interface{}{map[string]interface{}{}}}, "groupDetails": map[string]interface{}{"echelon": map[string]interface{}{"armyEchelon": "ARMY_ECHELON_INVALID"}}, "supplies": map[string]interface{}{"fuel": []interface{}{map[string]interface{}{}}}, "symbology": map[string]interface{}{"milStd2525C": map[string]interface{}{"sidc": "sidc"}}}, + ).WithStatus(http.StatusOK), + ) + err := WireMockClient.StubFor(stub) + require.NoError(t, err, "Failed to create WireMock stub") + + client := client.NewClient( + option.WithBaseURL( + WireMockBaseURL, + ), + ) + request := &Lattice.Entity{} + _, invocationErr := client.Entities.PublishEntity( + context.TODO(), + request, + ) + + require.NoError(t, invocationErr, "Client method call should succeed") + ok, countErr := WireMockClient.Verify(stub.Request(), 1) + require.NoError(t, countErr, "Failed to verify WireMock request was matched") + require.True(t, ok, "WireMock request was not matched") +} + +func TestEntitiesGetEntityWithWireMock( + t *testing.T, +) { + // wiremock client and server initialized in shared main_test.go + defer WireMockClient.Reset() + stub := gowiremock.Get(gowiremock.URLPathTemplate("/api/v1/entities/{entityId}")).WithPathParam( + "entityId", + gowiremock.Matching("entityId"), + ).WillReturnResponse( + gowiremock.NewResponse().WithJSONBody( + map[string]interface{}{"entityId": "entityId", "description": "description", "isLive": true, "createdTime": "2024-01-15T09:30:00Z", "expiryTime": "2024-01-15T09:30:00Z", "noExpiry": true, "status": map[string]interface{}{"code": 1, "message": "message", "details": []interface{}{map[string]interface{}{}}}, "location": map[string]interface{}{"position": map[string]interface{}{"latitudeDegrees": 1.1, "longitudeDegrees": 1.1, "altitudeHaeMeters": 1.1, "altitudeAglMeters": 1.1, "altitudeAsfMeters": 1.1, "pressureDepthMeters": 1.1}, "velocityEnu": map[string]interface{}{"e": 1.1, "n": 1.1, "u": 1.1}, "speedMps": 1.1, "acceleration": map[string]interface{}{"e": 1.1, "n": 1.1, "u": 1.1}, "attitudeEnu": map[string]interface{}{"x": 1.1, "y": 1.1, "z": 1.1, "w": 1.1}}, "locationUncertainty": map[string]interface{}{"positionEnuCov": map[string]interface{}{"mxx": 1.1, "mxy": 1.1, "mxz": 1.1, "myy": 1.1, "myz": 1.1, "mzz": 1.1}, "velocityEnuCov": map[string]interface{}{"mxx": 1.1, "mxy": 1.1, "mxz": 1.1, "myy": 1.1, "myz": 1.1, "mzz": 1.1}, "positionErrorEllipse": map[string]interface{}{"probability": 1.1, "semiMajorAxisM": 1.1, "semiMinorAxisM": 1.1, "orientationD": 1.1}}, "geoShape": map[string]interface{}{"line": map[string]interface{}{"positions": []interface{}{map[string]interface{}{}}}, "polygon": map[string]interface{}{"rings": []interface{}{map[string]interface{}{}}, "isRectangle": true}, "ellipse": map[string]interface{}{"semiMajorAxisM": 1.1, "semiMinorAxisM": 1.1, "orientationD": 1.1, "heightM": 1.1}, "ellipsoid": map[string]interface{}{"forwardAxisM": 1.1, "sideAxisM": 1.1, "upAxisM": 1.1}}, "geoDetails": map[string]interface{}{"type": "GEO_TYPE_INVALID", "controlArea": map[string]interface{}{"type": "CONTROL_AREA_TYPE_INVALID"}, "acm": map[string]interface{}{"acmType": "ACM_DETAIL_TYPE_INVALID", "acmDescription": "acmDescription"}}, "aliases": map[string]interface{}{"alternateIds": []interface{}{map[string]interface{}{}}, "name": "name"}, "tracked": map[string]interface{}{"trackQualityWrapper": 1, "sensorHits": 1, "numberOfObjects": map[string]interface{}{"lowerBound": 1, "upperBound": 1}, "radarCrossSection": 1.1, "lastMeasurementTime": "2024-01-15T09:30:00Z"}, "correlation": map[string]interface{}{"primary": map[string]interface{}{"secondaryEntityIds": []interface{}{"secondaryEntityIds"}}, "secondary": map[string]interface{}{"primaryEntityId": "primaryEntityId"}, "membership": map[string]interface{}{"correlationSetId": "correlationSetId"}, "decorrelation": map[string]interface{}{"decorrelatedEntities": []interface{}{map[string]interface{}{}}}}, "milView": map[string]interface{}{"disposition": "DISPOSITION_UNKNOWN", "environment": "ENVIRONMENT_UNKNOWN", "nationality": "NATIONALITY_INVALID"}, "ontology": map[string]interface{}{"platformType": "platformType", "specificType": "specificType", "template": "TEMPLATE_INVALID"}, "sensors": map[string]interface{}{"sensors": []interface{}{map[string]interface{}{}}}, "payloads": map[string]interface{}{"payloadConfigurations": []interface{}{map[string]interface{}{}}}, "powerState": map[string]interface{}{"sourceIdToState": map[string]interface{}{"key": map[string]interface{}{}}}, "provenance": map[string]interface{}{"integrationName": "integrationName", "dataType": "dataType", "sourceId": "sourceId", "sourceUpdateTime": "2024-01-15T09:30:00Z", "sourceDescription": "sourceDescription"}, "overrides": map[string]interface{}{"override": []interface{}{map[string]interface{}{}}}, "indicators": map[string]interface{}{"simulated": true, "exercise": true, "emergency": true, "c2": true, "egressable": true, "starred": true}, "targetPriority": map[string]interface{}{"highValueTarget": map[string]interface{}{"isHighValueTarget": true, "targetPriority": 1, "targetMatches": []interface{}{map[string]interface{}{}}, "isHighPayoffTarget": true}, "threat": map[string]interface{}{"isThreat": true}}, "signal": map[string]interface{}{"bandwidthHz": 1.1, "signalToNoiseRatio": 1.1, "emitterNotations": []interface{}{map[string]interface{}{}}, "pulseWidthS": 1.1, "scanCharacteristics": map[string]interface{}{"scanType": "SCAN_TYPE_INVALID", "scanPeriodS": 1.1}}, "transponderCodes": map[string]interface{}{"mode1": 1, "mode2": 1, "mode3": 1, "mode4InterrogationResponse": "INTERROGATION_RESPONSE_INVALID", "mode5": map[string]interface{}{"mode5InterrogationResponse": "INTERROGATION_RESPONSE_INVALID", "mode5": 1, "mode5PlatformId": 1}, "modeS": map[string]interface{}{"id": "id", "address": 1}}, "dataClassification": map[string]interface{}{"default": map[string]interface{}{"level": "CLASSIFICATION_LEVELS_INVALID", "caveats": []interface{}{"caveats"}}, "fields": []interface{}{map[string]interface{}{}}}, "taskCatalog": map[string]interface{}{"taskDefinitions": []interface{}{map[string]interface{}{}}}, "media": map[string]interface{}{"media": []interface{}{map[string]interface{}{}}}, "relationships": map[string]interface{}{"relationships": []interface{}{map[string]interface{}{}}}, "visualDetails": map[string]interface{}{"rangeRings": map[string]interface{}{"minDistanceM": 1.1, "maxDistanceM": 1.1, "ringCount": 1}}, "dimensions": map[string]interface{}{"lengthM": 1.1}, "routeDetails": map[string]interface{}{"destinationName": "destinationName", "estimatedArrivalTime": "2024-01-15T09:30:00Z"}, "schedules": map[string]interface{}{"schedules": []interface{}{map[string]interface{}{}}}, "health": map[string]interface{}{"connectionStatus": "CONNECTION_STATUS_INVALID", "healthStatus": "HEALTH_STATUS_INVALID", "components": []interface{}{map[string]interface{}{}}, "updateTime": "2024-01-15T09:30:00Z", "activeAlerts": []interface{}{map[string]interface{}{}}}, "groupDetails": map[string]interface{}{"echelon": map[string]interface{}{"armyEchelon": "ARMY_ECHELON_INVALID"}}, "supplies": map[string]interface{}{"fuel": []interface{}{map[string]interface{}{}}}, "symbology": map[string]interface{}{"milStd2525C": map[string]interface{}{"sidc": "sidc"}}}, + ).WithStatus(http.StatusOK), + ) + err := WireMockClient.StubFor(stub) + require.NoError(t, err, "Failed to create WireMock stub") + + client := client.NewClient( + option.WithBaseURL( + WireMockBaseURL, + ), + ) + _, invocationErr := client.Entities.GetEntity( + context.TODO(), + "entityId", + ) + + require.NoError(t, invocationErr, "Client method call should succeed") + ok, countErr := WireMockClient.Verify(stub.Request(), 1) + require.NoError(t, countErr, "Failed to verify WireMock request was matched") + require.True(t, ok, "WireMock request was not matched") +} + +func TestEntitiesOverrideEntityWithWireMock( + t *testing.T, +) { + // wiremock client and server initialized in shared main_test.go + defer WireMockClient.Reset() + stub := gowiremock.Put(gowiremock.URLPathTemplate("/api/v1/entities/{entityId}/override/{fieldPath}")).WithPathParam( + "entityId", + gowiremock.Matching("entityId"), + ).WithPathParam( + "fieldPath", + gowiremock.Matching("mil_view.disposition"), + ).WithBodyPattern(gowiremock.MatchesJsonSchema(`{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "required": [], + "properties": { + + }, + "additionalProperties": true + }`, "V202012")).WillReturnResponse( + gowiremock.NewResponse().WithJSONBody( + map[string]interface{}{"entityId": "entityId", "description": "description", "isLive": true, "createdTime": "2024-01-15T09:30:00Z", "expiryTime": "2024-01-15T09:30:00Z", "noExpiry": true, "status": map[string]interface{}{"code": 1, "message": "message", "details": []interface{}{map[string]interface{}{}}}, "location": map[string]interface{}{"position": map[string]interface{}{"latitudeDegrees": 1.1, "longitudeDegrees": 1.1, "altitudeHaeMeters": 1.1, "altitudeAglMeters": 1.1, "altitudeAsfMeters": 1.1, "pressureDepthMeters": 1.1}, "velocityEnu": map[string]interface{}{"e": 1.1, "n": 1.1, "u": 1.1}, "speedMps": 1.1, "acceleration": map[string]interface{}{"e": 1.1, "n": 1.1, "u": 1.1}, "attitudeEnu": map[string]interface{}{"x": 1.1, "y": 1.1, "z": 1.1, "w": 1.1}}, "locationUncertainty": map[string]interface{}{"positionEnuCov": map[string]interface{}{"mxx": 1.1, "mxy": 1.1, "mxz": 1.1, "myy": 1.1, "myz": 1.1, "mzz": 1.1}, "velocityEnuCov": map[string]interface{}{"mxx": 1.1, "mxy": 1.1, "mxz": 1.1, "myy": 1.1, "myz": 1.1, "mzz": 1.1}, "positionErrorEllipse": map[string]interface{}{"probability": 1.1, "semiMajorAxisM": 1.1, "semiMinorAxisM": 1.1, "orientationD": 1.1}}, "geoShape": map[string]interface{}{"line": map[string]interface{}{"positions": []interface{}{map[string]interface{}{}}}, "polygon": map[string]interface{}{"rings": []interface{}{map[string]interface{}{}}, "isRectangle": true}, "ellipse": map[string]interface{}{"semiMajorAxisM": 1.1, "semiMinorAxisM": 1.1, "orientationD": 1.1, "heightM": 1.1}, "ellipsoid": map[string]interface{}{"forwardAxisM": 1.1, "sideAxisM": 1.1, "upAxisM": 1.1}}, "geoDetails": map[string]interface{}{"type": "GEO_TYPE_INVALID", "controlArea": map[string]interface{}{"type": "CONTROL_AREA_TYPE_INVALID"}, "acm": map[string]interface{}{"acmType": "ACM_DETAIL_TYPE_INVALID", "acmDescription": "acmDescription"}}, "aliases": map[string]interface{}{"alternateIds": []interface{}{map[string]interface{}{}}, "name": "name"}, "tracked": map[string]interface{}{"trackQualityWrapper": 1, "sensorHits": 1, "numberOfObjects": map[string]interface{}{"lowerBound": 1, "upperBound": 1}, "radarCrossSection": 1.1, "lastMeasurementTime": "2024-01-15T09:30:00Z"}, "correlation": map[string]interface{}{"primary": map[string]interface{}{"secondaryEntityIds": []interface{}{"secondaryEntityIds"}}, "secondary": map[string]interface{}{"primaryEntityId": "primaryEntityId"}, "membership": map[string]interface{}{"correlationSetId": "correlationSetId"}, "decorrelation": map[string]interface{}{"decorrelatedEntities": []interface{}{map[string]interface{}{}}}}, "milView": map[string]interface{}{"disposition": "DISPOSITION_UNKNOWN", "environment": "ENVIRONMENT_UNKNOWN", "nationality": "NATIONALITY_INVALID"}, "ontology": map[string]interface{}{"platformType": "platformType", "specificType": "specificType", "template": "TEMPLATE_INVALID"}, "sensors": map[string]interface{}{"sensors": []interface{}{map[string]interface{}{}}}, "payloads": map[string]interface{}{"payloadConfigurations": []interface{}{map[string]interface{}{}}}, "powerState": map[string]interface{}{"sourceIdToState": map[string]interface{}{"key": map[string]interface{}{}}}, "provenance": map[string]interface{}{"integrationName": "integrationName", "dataType": "dataType", "sourceId": "sourceId", "sourceUpdateTime": "2024-01-15T09:30:00Z", "sourceDescription": "sourceDescription"}, "overrides": map[string]interface{}{"override": []interface{}{map[string]interface{}{}}}, "indicators": map[string]interface{}{"simulated": true, "exercise": true, "emergency": true, "c2": true, "egressable": true, "starred": true}, "targetPriority": map[string]interface{}{"highValueTarget": map[string]interface{}{"isHighValueTarget": true, "targetPriority": 1, "targetMatches": []interface{}{map[string]interface{}{}}, "isHighPayoffTarget": true}, "threat": map[string]interface{}{"isThreat": true}}, "signal": map[string]interface{}{"bandwidthHz": 1.1, "signalToNoiseRatio": 1.1, "emitterNotations": []interface{}{map[string]interface{}{}}, "pulseWidthS": 1.1, "scanCharacteristics": map[string]interface{}{"scanType": "SCAN_TYPE_INVALID", "scanPeriodS": 1.1}}, "transponderCodes": map[string]interface{}{"mode1": 1, "mode2": 1, "mode3": 1, "mode4InterrogationResponse": "INTERROGATION_RESPONSE_INVALID", "mode5": map[string]interface{}{"mode5InterrogationResponse": "INTERROGATION_RESPONSE_INVALID", "mode5": 1, "mode5PlatformId": 1}, "modeS": map[string]interface{}{"id": "id", "address": 1}}, "dataClassification": map[string]interface{}{"default": map[string]interface{}{"level": "CLASSIFICATION_LEVELS_INVALID", "caveats": []interface{}{"caveats"}}, "fields": []interface{}{map[string]interface{}{}}}, "taskCatalog": map[string]interface{}{"taskDefinitions": []interface{}{map[string]interface{}{}}}, "media": map[string]interface{}{"media": []interface{}{map[string]interface{}{}}}, "relationships": map[string]interface{}{"relationships": []interface{}{map[string]interface{}{}}}, "visualDetails": map[string]interface{}{"rangeRings": map[string]interface{}{"minDistanceM": 1.1, "maxDistanceM": 1.1, "ringCount": 1}}, "dimensions": map[string]interface{}{"lengthM": 1.1}, "routeDetails": map[string]interface{}{"destinationName": "destinationName", "estimatedArrivalTime": "2024-01-15T09:30:00Z"}, "schedules": map[string]interface{}{"schedules": []interface{}{map[string]interface{}{}}}, "health": map[string]interface{}{"connectionStatus": "CONNECTION_STATUS_INVALID", "healthStatus": "HEALTH_STATUS_INVALID", "components": []interface{}{map[string]interface{}{}}, "updateTime": "2024-01-15T09:30:00Z", "activeAlerts": []interface{}{map[string]interface{}{}}}, "groupDetails": map[string]interface{}{"echelon": map[string]interface{}{"armyEchelon": "ARMY_ECHELON_INVALID"}}, "supplies": map[string]interface{}{"fuel": []interface{}{map[string]interface{}{}}}, "symbology": map[string]interface{}{"milStd2525C": map[string]interface{}{"sidc": "sidc"}}}, + ).WithStatus(http.StatusOK), + ) + err := WireMockClient.StubFor(stub) + require.NoError(t, err, "Failed to create WireMock stub") + + client := client.NewClient( + option.WithBaseURL( + WireMockBaseURL, + ), + ) + request := &Lattice.EntityOverride{} + _, invocationErr := client.Entities.OverrideEntity( + context.TODO(), + "entityId", + "mil_view.disposition", + request, + ) + + require.NoError(t, invocationErr, "Client method call should succeed") + ok, countErr := WireMockClient.Verify(stub.Request(), 1) + require.NoError(t, countErr, "Failed to verify WireMock request was matched") + require.True(t, ok, "WireMock request was not matched") +} + +func TestEntitiesRemoveEntityOverrideWithWireMock( + t *testing.T, +) { + // wiremock client and server initialized in shared main_test.go + defer WireMockClient.Reset() + stub := gowiremock.Delete(gowiremock.URLPathTemplate("/api/v1/entities/{entityId}/override/{fieldPath}")).WithPathParam( + "entityId", + gowiremock.Matching("entityId"), + ).WithPathParam( + "fieldPath", + gowiremock.Matching("mil_view.disposition"), + ).WillReturnResponse( + gowiremock.NewResponse().WithJSONBody( + map[string]interface{}{"entityId": "entityId", "description": "description", "isLive": true, "createdTime": "2024-01-15T09:30:00Z", "expiryTime": "2024-01-15T09:30:00Z", "noExpiry": true, "status": map[string]interface{}{"code": 1, "message": "message", "details": []interface{}{map[string]interface{}{}}}, "location": map[string]interface{}{"position": map[string]interface{}{"latitudeDegrees": 1.1, "longitudeDegrees": 1.1, "altitudeHaeMeters": 1.1, "altitudeAglMeters": 1.1, "altitudeAsfMeters": 1.1, "pressureDepthMeters": 1.1}, "velocityEnu": map[string]interface{}{"e": 1.1, "n": 1.1, "u": 1.1}, "speedMps": 1.1, "acceleration": map[string]interface{}{"e": 1.1, "n": 1.1, "u": 1.1}, "attitudeEnu": map[string]interface{}{"x": 1.1, "y": 1.1, "z": 1.1, "w": 1.1}}, "locationUncertainty": map[string]interface{}{"positionEnuCov": map[string]interface{}{"mxx": 1.1, "mxy": 1.1, "mxz": 1.1, "myy": 1.1, "myz": 1.1, "mzz": 1.1}, "velocityEnuCov": map[string]interface{}{"mxx": 1.1, "mxy": 1.1, "mxz": 1.1, "myy": 1.1, "myz": 1.1, "mzz": 1.1}, "positionErrorEllipse": map[string]interface{}{"probability": 1.1, "semiMajorAxisM": 1.1, "semiMinorAxisM": 1.1, "orientationD": 1.1}}, "geoShape": map[string]interface{}{"line": map[string]interface{}{"positions": []interface{}{map[string]interface{}{}}}, "polygon": map[string]interface{}{"rings": []interface{}{map[string]interface{}{}}, "isRectangle": true}, "ellipse": map[string]interface{}{"semiMajorAxisM": 1.1, "semiMinorAxisM": 1.1, "orientationD": 1.1, "heightM": 1.1}, "ellipsoid": map[string]interface{}{"forwardAxisM": 1.1, "sideAxisM": 1.1, "upAxisM": 1.1}}, "geoDetails": map[string]interface{}{"type": "GEO_TYPE_INVALID", "controlArea": map[string]interface{}{"type": "CONTROL_AREA_TYPE_INVALID"}, "acm": map[string]interface{}{"acmType": "ACM_DETAIL_TYPE_INVALID", "acmDescription": "acmDescription"}}, "aliases": map[string]interface{}{"alternateIds": []interface{}{map[string]interface{}{}}, "name": "name"}, "tracked": map[string]interface{}{"trackQualityWrapper": 1, "sensorHits": 1, "numberOfObjects": map[string]interface{}{"lowerBound": 1, "upperBound": 1}, "radarCrossSection": 1.1, "lastMeasurementTime": "2024-01-15T09:30:00Z"}, "correlation": map[string]interface{}{"primary": map[string]interface{}{"secondaryEntityIds": []interface{}{"secondaryEntityIds"}}, "secondary": map[string]interface{}{"primaryEntityId": "primaryEntityId"}, "membership": map[string]interface{}{"correlationSetId": "correlationSetId"}, "decorrelation": map[string]interface{}{"decorrelatedEntities": []interface{}{map[string]interface{}{}}}}, "milView": map[string]interface{}{"disposition": "DISPOSITION_UNKNOWN", "environment": "ENVIRONMENT_UNKNOWN", "nationality": "NATIONALITY_INVALID"}, "ontology": map[string]interface{}{"platformType": "platformType", "specificType": "specificType", "template": "TEMPLATE_INVALID"}, "sensors": map[string]interface{}{"sensors": []interface{}{map[string]interface{}{}}}, "payloads": map[string]interface{}{"payloadConfigurations": []interface{}{map[string]interface{}{}}}, "powerState": map[string]interface{}{"sourceIdToState": map[string]interface{}{"key": map[string]interface{}{}}}, "provenance": map[string]interface{}{"integrationName": "integrationName", "dataType": "dataType", "sourceId": "sourceId", "sourceUpdateTime": "2024-01-15T09:30:00Z", "sourceDescription": "sourceDescription"}, "overrides": map[string]interface{}{"override": []interface{}{map[string]interface{}{}}}, "indicators": map[string]interface{}{"simulated": true, "exercise": true, "emergency": true, "c2": true, "egressable": true, "starred": true}, "targetPriority": map[string]interface{}{"highValueTarget": map[string]interface{}{"isHighValueTarget": true, "targetPriority": 1, "targetMatches": []interface{}{map[string]interface{}{}}, "isHighPayoffTarget": true}, "threat": map[string]interface{}{"isThreat": true}}, "signal": map[string]interface{}{"bandwidthHz": 1.1, "signalToNoiseRatio": 1.1, "emitterNotations": []interface{}{map[string]interface{}{}}, "pulseWidthS": 1.1, "scanCharacteristics": map[string]interface{}{"scanType": "SCAN_TYPE_INVALID", "scanPeriodS": 1.1}}, "transponderCodes": map[string]interface{}{"mode1": 1, "mode2": 1, "mode3": 1, "mode4InterrogationResponse": "INTERROGATION_RESPONSE_INVALID", "mode5": map[string]interface{}{"mode5InterrogationResponse": "INTERROGATION_RESPONSE_INVALID", "mode5": 1, "mode5PlatformId": 1}, "modeS": map[string]interface{}{"id": "id", "address": 1}}, "dataClassification": map[string]interface{}{"default": map[string]interface{}{"level": "CLASSIFICATION_LEVELS_INVALID", "caveats": []interface{}{"caveats"}}, "fields": []interface{}{map[string]interface{}{}}}, "taskCatalog": map[string]interface{}{"taskDefinitions": []interface{}{map[string]interface{}{}}}, "media": map[string]interface{}{"media": []interface{}{map[string]interface{}{}}}, "relationships": map[string]interface{}{"relationships": []interface{}{map[string]interface{}{}}}, "visualDetails": map[string]interface{}{"rangeRings": map[string]interface{}{"minDistanceM": 1.1, "maxDistanceM": 1.1, "ringCount": 1}}, "dimensions": map[string]interface{}{"lengthM": 1.1}, "routeDetails": map[string]interface{}{"destinationName": "destinationName", "estimatedArrivalTime": "2024-01-15T09:30:00Z"}, "schedules": map[string]interface{}{"schedules": []interface{}{map[string]interface{}{}}}, "health": map[string]interface{}{"connectionStatus": "CONNECTION_STATUS_INVALID", "healthStatus": "HEALTH_STATUS_INVALID", "components": []interface{}{map[string]interface{}{}}, "updateTime": "2024-01-15T09:30:00Z", "activeAlerts": []interface{}{map[string]interface{}{}}}, "groupDetails": map[string]interface{}{"echelon": map[string]interface{}{"armyEchelon": "ARMY_ECHELON_INVALID"}}, "supplies": map[string]interface{}{"fuel": []interface{}{map[string]interface{}{}}}, "symbology": map[string]interface{}{"milStd2525C": map[string]interface{}{"sidc": "sidc"}}}, + ).WithStatus(http.StatusOK), + ) + err := WireMockClient.StubFor(stub) + require.NoError(t, err, "Failed to create WireMock stub") + + client := client.NewClient( + option.WithBaseURL( + WireMockBaseURL, + ), + ) + _, invocationErr := client.Entities.RemoveEntityOverride( + context.TODO(), + "entityId", + "mil_view.disposition", + ) + + require.NoError(t, invocationErr, "Client method call should succeed") + ok, countErr := WireMockClient.Verify(stub.Request(), 1) + require.NoError(t, countErr, "Failed to verify WireMock request was matched") + require.True(t, ok, "WireMock request was not matched") +} + +func TestEntitiesLongPollEntityEventsWithWireMock( + t *testing.T, +) { + // wiremock client and server initialized in shared main_test.go + defer WireMockClient.Reset() + stub := gowiremock.Post(gowiremock.URLPathTemplate("/api/v1/entities/events")).WithBodyPattern(gowiremock.MatchesJsonSchema(`{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "required": ["sessionToken"], + "properties": { + "sessionToken": {"type": "string"} + }, + "additionalProperties": true + }`, "V202012")).WillReturnResponse( + gowiremock.NewResponse().WithJSONBody( + map[string]interface{}{"sessionToken": "sessionToken", "entityEvents": []interface{}{map[string]interface{}{"eventType": "EVENT_TYPE_INVALID", "time": "2024-01-15T09:30:00Z"}}}, + ).WithStatus(http.StatusOK), + ) + err := WireMockClient.StubFor(stub) + require.NoError(t, err, "Failed to create WireMock stub") + + client := client.NewClient( + option.WithBaseURL( + WireMockBaseURL, + ), + ) + request := &Lattice.EntityEventRequest{ + SessionToken: "sessionToken", + } + _, invocationErr := client.Entities.LongPollEntityEvents( + context.TODO(), + request, + ) + + require.NoError(t, invocationErr, "Client method call should succeed") + ok, countErr := WireMockClient.Verify(stub.Request(), 1) + require.NoError(t, countErr, "Failed to verify WireMock request was matched") + require.True(t, ok, "WireMock request was not matched") +} + +func TestEntitiesStreamEntitiesWithWireMock( + t *testing.T, +) { + // wiremock client and server initialized in shared main_test.go + defer WireMockClient.Reset() + stub := gowiremock.Post(gowiremock.URLPathTemplate("/api/v1/entities/stream")).WithBodyPattern(gowiremock.MatchesJsonSchema(`{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "required": [], + "properties": { + + }, + "additionalProperties": true + }`, "V202012")).WillReturnResponse( + gowiremock.NewResponse().WithJSONBody( + map[string]interface{}{}, + ).WithStatus(http.StatusOK), + ) + err := WireMockClient.StubFor(stub) + require.NoError(t, err, "Failed to create WireMock stub") + + client := client.NewClient( + option.WithBaseURL( + WireMockBaseURL, + ), + ) + request := &Lattice.EntityStreamRequest{} + _, invocationErr := client.Entities.StreamEntities( + context.TODO(), + request, + ) + + require.NoError(t, invocationErr, "Client method call should succeed") + ok, countErr := WireMockClient.Verify(stub.Request(), 1) + require.NoError(t, countErr, "Failed to verify WireMock request was matched") + require.True(t, ok, "WireMock request was not matched") +} diff --git a/go.mod b/go.mod index 3ab8143..b9df8ec 100644 --- a/go.mod +++ b/go.mod @@ -6,11 +6,61 @@ toolchain go1.23.8 require github.com/google/uuid v1.6.0 -require github.com/stretchr/testify v1.8.4 +require github.com/stretchr/testify v1.9.0 require gopkg.in/yaml.v3 v3.0.1 // indirect +require github.com/wiremock/wiremock-testcontainers-go v1.0.0-alpha-9 + +require github.com/wiremock/go-wiremock v1.14.0 + +require github.com/containerd/containerd v1.7.27 // indirect + require ( + dario.cat/mergo v1.0.0 // indirect + github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect + github.com/Microsoft/go-winio v0.6.2 // indirect + github.com/Microsoft/hcsshim v0.11.7 // indirect + github.com/cenkalti/backoff/v4 v4.2.1 // indirect + github.com/containerd/log v0.1.0 // indirect + github.com/containerd/platforms v0.2.1 // indirect + github.com/cpuguy83/dockercfg v0.3.1 // indirect github.com/davecgh/go-spew v1.1.1 // indirect + github.com/distribution/reference v0.6.0 // indirect + github.com/docker/docker v25.0.5+incompatible // indirect + github.com/docker/go-connections v0.5.0 // indirect + github.com/docker/go-units v0.5.0 // indirect + github.com/felixge/httpsnoop v1.0.4 // indirect + github.com/go-logr/logr v1.4.2 // indirect + github.com/go-logr/stdr v1.2.2 // indirect + github.com/go-ole/go-ole v1.2.6 // indirect + github.com/gogo/protobuf v1.3.2 // indirect + github.com/klauspost/compress v1.16.7 // indirect + github.com/kr/text v0.2.0 // indirect + github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect + github.com/magiconair/properties v1.8.7 // indirect + github.com/moby/patternmatcher v0.6.0 // indirect + github.com/moby/sys/sequential v0.5.0 // indirect + github.com/moby/sys/user v0.3.0 // indirect + github.com/moby/sys/userns v0.1.0 // indirect + github.com/moby/term v0.5.0 // indirect + github.com/morikuni/aec v1.0.0 // indirect + github.com/opencontainers/go-digest v1.0.0 // indirect + github.com/opencontainers/image-spec v1.1.0 // indirect + github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect + github.com/shirou/gopsutil/v3 v3.23.12 // indirect + github.com/shoenig/go-m1cpu v0.1.6 // indirect + github.com/sirupsen/logrus v1.9.3 // indirect + github.com/testcontainers/testcontainers-go v0.31.0 // indirect + github.com/tklauser/go-sysconf v0.3.12 // indirect + github.com/tklauser/numcpus v0.6.1 // indirect + github.com/yusufpapurcu/wmi v1.2.3 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 // indirect + go.opentelemetry.io/otel v1.24.0 // indirect + go.opentelemetry.io/otel/metric v1.24.0 // indirect + go.opentelemetry.io/otel/trace v1.24.0 // indirect + golang.org/x/crypto v0.31.0 // indirect + golang.org/x/sys v0.28.0 // indirect ) diff --git a/go.sum b/go.sum index fcca6d1..ac8057d 100644 --- a/go.sum +++ b/go.sum @@ -1,12 +1,199 @@ +dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk= +dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= +github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 h1:bvDV9vkmnHYOMsOr4WLk+Vo07yKIzd94sVoIqshQ4bU= +github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24/go.mod h1:8o94RPi1/7XTJvwPpRSzSUedZrtlirdB3r9Z20bi2f8= +github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8= +github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= +github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= +github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= +github.com/Microsoft/hcsshim v0.11.7 h1:vl/nj3Bar/CvJSYo7gIQPyRWc9f3c6IeSNavBTSZNZQ= +github.com/Microsoft/hcsshim v0.11.7/go.mod h1:MV8xMfmECjl5HdO7U/3/hFVnkmSBjAjmA09d4bExKcU= +github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM= +github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= +github.com/containerd/containerd v1.7.27 h1:yFyEyojddO3MIGVER2xJLWoCIn+Up4GaHFquP7hsFII= +github.com/containerd/containerd v1.7.27/go.mod h1:xZmPnl75Vc+BLGt4MIfu6bp+fy03gdHAn9bz+FreFR0= +github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I= +github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo= +github.com/containerd/platforms v0.2.1 h1:zvwtM3rz2YHPQsF2CHYM8+KtB5dvhISiXh5ZpSBQv6A= +github.com/containerd/platforms v0.2.1/go.mod h1:XHCb+2/hzowdiut9rkudds9bE5yJ7npe7dG/wG+uFPw= +github.com/cpuguy83/dockercfg v0.3.1 h1:/FpZ+JaygUR/lZP2NlFI2DVfrOEMAIKP5wWEJdoYe9E= +github.com/cpuguy83/dockercfg v0.3.1/go.mod h1:sugsbF4//dDlL/i+S+rtpIWp+5h0BHJHfjj5/jFyUJc= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY= +github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk= +github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= +github.com/docker/docker v25.0.5+incompatible h1:UmQydMduGkrD5nQde1mecF/YnSbTOaPeFIeP5C4W+DE= +github.com/docker/docker v25.0.5+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c= +github.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6GLaXnqyDdmEXc= +github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= +github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= +github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= +github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= +github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= +github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= +github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= +github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= +github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= +github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= +github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0 h1:YBftPWNWd4WwGqtY2yeZL2ef8rHAxPBD8KFhJpmcqms= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0/go.mod h1:YN5jB8ie0yfIUg6VvR9Kz84aCaG7AsGZnLjhHbUqwPg= +github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/klauspost/compress v1.16.7 h1:2mk3MPGNzKyxErAw8YaohYh69+pa4sIQSC0fPGCFR9I= +github.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= +github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= +github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4= +github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I= +github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= +github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= +github.com/moby/patternmatcher v0.6.0 h1:GmP9lR19aU5GqSSFko+5pRqHi+Ohk1O69aFiKkVGiPk= +github.com/moby/patternmatcher v0.6.0/go.mod h1:hDPoyOpDY7OrrMDLaYoY3hf52gNCR/YOUYxkhApJIxc= +github.com/moby/sys/sequential v0.5.0 h1:OPvI35Lzn9K04PBbCLW0g4LcFAJgHsvXsRyewg5lXtc= +github.com/moby/sys/sequential v0.5.0/go.mod h1:tH2cOOs5V9MlPiXcQzRC+eEyab644PWKGRYaaV5ZZlo= +github.com/moby/sys/user v0.3.0 h1:9ni5DlcW5an3SvRSx4MouotOygvzaXbaSrc/wGDFWPo= +github.com/moby/sys/user v0.3.0/go.mod h1:bG+tYYYJgaMtRKgEmuueC0hJEAZWwtIbZTB+85uoHjs= +github.com/moby/sys/userns v0.1.0 h1:tVLXkFOxVu9A64/yh59slHVv9ahO9UIev4JZusOLG/g= +github.com/moby/sys/userns v0.1.0/go.mod h1:IHUYgu/kao6N8YZlp9Cf444ySSvCmDlmzUcYfDHOl28= +github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0= +github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y= +github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= +github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= +github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= +github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= +github.com/opencontainers/image-spec v1.1.0 h1:8SG7/vwALn54lVB/0yZ/MMwhFrPYtpEHQb2IpWsCzug= +github.com/opencontainers/image-spec v1.1.0/go.mod h1:W4s4sFTMaBeK1BQLXbG4AdM2szdn85PY75RI83NrTrM= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c h1:ncq/mPwQF4JjgDlrVEn3C11VoGHZN7m8qihwgMEtzYw= +github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE= +github.com/rogpeppe/go-internal v1.8.1 h1:geMPLpDpQOgVyCg5z5GoRwLHepNdb71NXb67XFkP+Eg= +github.com/rogpeppe/go-internal v1.8.1/go.mod h1:JeRgkft04UBgHMgCIwADu4Pn6Mtm5d4nPKWu0nJ5d+o= +github.com/shirou/gopsutil/v3 v3.23.12 h1:z90NtUkp3bMtmICZKpC4+WaknU1eXtp5vtbQ11DgpE4= +github.com/shirou/gopsutil/v3 v3.23.12/go.mod h1:1FrWgea594Jp7qmjHUUPlJDTPgcsb9mGnXDxavtikzM= +github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM= +github.com/shoenig/go-m1cpu v0.1.6/go.mod h1:1JJMcUBvfNwpq05QDQVAnx3gUHr9IYF7GNg9SUEw2VQ= +github.com/shoenig/test v0.6.4 h1:kVTaSd7WLz5WZ2IaoM0RSzRsUD+m8wRR+5qvntpn4LU= +github.com/shoenig/test v0.6.4/go.mod h1:byHiCGXqrVaflBLAMq/srcZIHynQPQgeyvkvXnjqq0k= +github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= +github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/testcontainers/testcontainers-go v0.31.0 h1:W0VwIhcEVhRflwL9as3dhY6jXjVCA27AkmbnZ+UTh3U= +github.com/testcontainers/testcontainers-go v0.31.0/go.mod h1:D2lAoA0zUFiSY+eAflqK5mcUx/A5hrrORaEQrd0SefI= +github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU= +github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI= +github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk= +github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY= +github.com/wiremock/go-wiremock v1.14.0 h1:cVAV98Odg+hySEYKDRUasVo30q7JE/ysrdx5qOmF4f4= +github.com/wiremock/go-wiremock v1.14.0/go.mod h1:T5XkKnsKS2asycbUrk2cpxXTEXwa6klHfCWVN8BkhkU= +github.com/wiremock/wiremock-testcontainers-go v1.0.0-alpha-9 h1:LUa3up/6uLDRo6U++9VtLHfsJKQjwqHyHmdXuT3cqdU= +github.com/wiremock/wiremock-testcontainers-go v1.0.0-alpha-9/go.mod h1:nWMqyEkwfGVBm8gOpQ41RhUWUqSfsFhlIrxMtO9NziU= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yusufpapurcu/wmi v1.2.3 h1:E1ctvB7uKFMOJw3fdOW32DwGE9I7t++CRUEMKvFoFiw= +github.com/yusufpapurcu/wmi v1.2.3/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 h1:jq9TW8u3so/bN+JPT166wjOI6/vQPF6Xe7nMNIltagk= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0/go.mod h1:p8pYQP+m5XfbZm9fxtSKAbM6oIllS7s2AfxrChvc7iw= +go.opentelemetry.io/otel v1.24.0 h1:0LAOdjNmQeSTzGBzduGe/rU4tZhMwL5rWgtp9Ku5Jfo= +go.opentelemetry.io/otel v1.24.0/go.mod h1:W7b9Ozg4nkF5tWI5zsXkaKKDjdVjpD4oAt9Qi/MArHo= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.19.0 h1:Mne5On7VWdx7omSrSSZvM4Kw7cS7NQkOOmLcgscI51U= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.19.0/go.mod h1:IPtUMKL4O3tH5y+iXVyAXqpAwMuzC1IrxVS81rummfE= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.19.0 h1:IeMeyr1aBvBiPVYihXIaeIZba6b8E1bYp7lbdxK8CQg= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.19.0/go.mod h1:oVdCUtjq9MK9BlS7TtucsQwUcXcymNiEDjgDD2jMtZU= +go.opentelemetry.io/otel/metric v1.24.0 h1:6EhoGWWK28x1fbpA4tYTOWBkPefTDQnb8WSGXlc88kI= +go.opentelemetry.io/otel/metric v1.24.0/go.mod h1:VYhLe1rFfxuTXLgj4CBiyz+9WYBA8pNGJgDcSFRKBco= +go.opentelemetry.io/otel/sdk v1.21.0 h1:FTt8qirL1EysG6sTQRZ5TokkU8d0ugCj8htOgThZXQ8= +go.opentelemetry.io/otel/sdk v1.21.0/go.mod h1:Nna6Yv7PWTdgJHVRD9hIYywQBRx7pbox6nwBnZIxl/E= +go.opentelemetry.io/otel/trace v1.24.0 h1:CsKnnL4dUAr/0llH9FKuc698G04IrpWV0MQA/Y1YELI= +go.opentelemetry.io/otel/trace v1.24.0/go.mod h1:HPc3Xr/cOApsBI154IU0OI0HJexz+aw5uPdbs3UCjNU= +go.opentelemetry.io/proto/otlp v1.0.0 h1:T0TX0tmXU8a3CbNXzEKGeU5mIVOdf0oykP+u2lIVU/I= +go.opentelemetry.io/proto/otlp v1.0.0/go.mod h1:Sy6pihPLfYHkr3NkUbEhGHFhINUSI/v80hjKIs5JXpM= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= +golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I= +golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= +golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/term v0.27.0 h1:WP60Sv1nlK1T6SupCHbXzSaN0b9wUmsPoRS9b61A23Q= +golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= +golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= +golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= +golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/genproto v0.0.0-20231211222908-989df2bf70f3 h1:1hfbdAfFbkmpg41000wDVqr7jUpK/Yo+LPnIxxGzmkg= +google.golang.org/genproto/googleapis/api v0.0.0-20231120223509-83a465c0220f h1:2yNACc1O40tTnrsbk9Cv6oxiW8pxI/pXj0wRtdlYmgY= +google.golang.org/genproto/googleapis/api v0.0.0-20231120223509-83a465c0220f/go.mod h1:Uy9bTZJqmfrw2rIBxgGLnamc78euZULUBrLZ9XTITKI= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240401170217-c3f982113cda h1:LI5DOvAxUPMv/50agcLLoo+AdWc1irS9Rzz4vPuD1V4= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240401170217-c3f982113cda/go.mod h1:WtryC6hu0hhx87FDGxWCDptyssuo68sk10vYjF+T9fY= +google.golang.org/grpc v1.59.0 h1:Z5Iec2pjwb+LEOqzpB2MR12/eKFhDPhuqW91O+4bwUk= +google.golang.org/grpc v1.59.0/go.mod h1:aUPDwccQo6OTjy7Hct4AfBPD1GptF4fyUjIkQ9YtF98= +google.golang.org/protobuf v1.35.2 h1:8Ar7bF+apOIoThw1EdZl0p1oWvMqTHmpA2fRTyZO8io= +google.golang.org/protobuf v1.35.2/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gotest.tools/v3 v3.5.0 h1:Ljk6PdHdOhAb5aDMWXjDLMMhph+BpztA4v1QdqEW2eY= +gotest.tools/v3 v3.5.0/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU= diff --git a/objects/objects_test/objects_test.go b/objects/objects_test/objects_test.go new file mode 100644 index 0000000..c9136b5 --- /dev/null +++ b/objects/objects_test/objects_test.go @@ -0,0 +1,237 @@ +// Code generated by Fern. DO NOT EDIT. + +package objects_test + +import ( + context "context" + fmt "fmt" + v3 "github.com/anduril/lattice-sdk-go/v3" + client "github.com/anduril/lattice-sdk-go/v3/client" + option "github.com/anduril/lattice-sdk-go/v3/option" + require "github.com/stretchr/testify/require" + gowiremock "github.com/wiremock/go-wiremock" + wiremocktestcontainersgo "github.com/wiremock/wiremock-testcontainers-go" + http "net/http" + os "os" + testing "testing" +) + +// TestMain sets up shared test fixtures for all tests in this package// Global test fixtures +var ( + WireMockContainer *wiremocktestcontainersgo.WireMockContainer + WireMockBaseURL string + WireMockClient *gowiremock.Client +) + +// TestMain sets up shared test fixtures for all tests in this package +func TestMain(m *testing.M) { + // Setup shared WireMock container + ctx := context.Background() + container, err := wiremocktestcontainersgo.RunContainerAndStopOnCleanup( + ctx, + &testing.T{}, + wiremocktestcontainersgo.WithImage("docker.io/wiremock/wiremock:3.9.1"), + ) + if err != nil { + fmt.Printf("Failed to start WireMock container: %v\n", err) + os.Exit(1) + } + + // Store global references + WireMockContainer = container + + // Try to get the base URL using the standard method first + baseURL, err := container.Endpoint(ctx, "") + if err == nil { + // Standard method worked (running outside DinD) + // This uses the mapped port (e.g., localhost:59553) + WireMockBaseURL = "http://" + baseURL + WireMockClient = container.Client + } else { + // Standard method failed, use internal IP fallback (DinD environment) + fmt.Printf("Standard endpoint resolution failed, using internal IP fallback: %v\n", err) + + inspect, err := container.Inspect(ctx) + if err != nil { + fmt.Printf("Failed to inspect WireMock container: %v\n", err) + os.Exit(1) + } + + // Find the IP address from the container's networks + var containerIP string + for _, network := range inspect.NetworkSettings.Networks { + if network.IPAddress != "" { + containerIP = network.IPAddress + break + } + } + + if containerIP == "" { + fmt.Printf("Failed to get WireMock container IP address\n") + os.Exit(1) + } + + // In DinD, use the internal port directly (8080 for WireMock HTTP) + // Don't use the mapped port since it doesn't exist in this environment + WireMockBaseURL = fmt.Sprintf("http://%s:8080", containerIP) + + // The container.Client was created with a bad URL, so we need a new one + WireMockClient = gowiremock.NewClient(WireMockBaseURL) + } + + fmt.Printf("WireMock available at: %s\n", WireMockBaseURL) + + // Run all tests + code := m.Run() + + // Cleanup + if WireMockContainer != nil { + WireMockContainer.Terminate(ctx) + } + + // Exit with the same code as the tests + os.Exit(code) +} + +func TestObjectsListObjectsWithWireMock( + t *testing.T, +) { + // wiremock client and server initialized in shared main_test.go + defer WireMockClient.Reset() + stub := gowiremock.Get(gowiremock.URLPathTemplate("/api/v1/objects")).WillReturnResponse( + gowiremock.NewResponse().WithJSONBody( + map[string]interface{}{"path_metadatas": []interface{}{map[string]interface{}{"content_identifier": map[string]interface{}{"path": "path", "checksum": "checksum"}, "size_bytes": 1000000, "last_updated_at": "2024-01-15T09:30:00Z", "expiry_time": "2024-01-15T09:30:00Z"}}, "next_page_token": "next_page_token"}, + ).WithStatus(http.StatusOK), + ) + err := WireMockClient.StubFor(stub) + require.NoError(t, err, "Failed to create WireMock stub") + + client := client.NewClient( + option.WithBaseURL( + WireMockBaseURL, + ), + ) + request := &Lattice.ListObjectsRequest{ + Prefix: Lattice.String( + "prefix", + ), + SinceTimestamp: Lattice.Time( + Lattice.MustParseDateTime( + "2024-01-15T09:30:00Z", + ), + ), + PageToken: Lattice.String( + "pageToken", + ), + AllObjectsInMesh: Lattice.Bool( + true, + ), + } + _, invocationErr := client.Objects.ListObjects( + context.TODO(), + request, + ) + + require.NoError(t, invocationErr, "Client method call should succeed") + ok, countErr := WireMockClient.Verify(stub.Request(), 1) + require.NoError(t, countErr, "Failed to verify WireMock request was matched") + require.True(t, ok, "WireMock request was not matched") +} + +func TestObjectsGetObjectWithWireMock( + t *testing.T, +) { + // wiremock client and server initialized in shared main_test.go + defer WireMockClient.Reset() + stub := gowiremock.Get(gowiremock.URLPathTemplate("/api/v1/objects/{objectPath}")).WithPathParam( + "objectPath", + gowiremock.Matching("objectPath"), + ).WillReturnResponse( + gowiremock.NewResponse().WithJSONBody( + map[string]interface{}{}, + ).WithStatus(http.StatusOK), + ) + err := WireMockClient.StubFor(stub) + require.NoError(t, err, "Failed to create WireMock stub") + + client := client.NewClient( + option.WithBaseURL( + WireMockBaseURL, + ), + ) + request := &Lattice.GetObjectRequest{} + _, invocationErr := client.Objects.GetObject( + context.TODO(), + "objectPath", + request, + ) + + require.NoError(t, invocationErr, "Client method call should succeed") + ok, countErr := WireMockClient.Verify(stub.Request(), 1) + require.NoError(t, countErr, "Failed to verify WireMock request was matched") + require.True(t, ok, "WireMock request was not matched") +} + +func TestObjectsDeleteObjectWithWireMock( + t *testing.T, +) { + // wiremock client and server initialized in shared main_test.go + defer WireMockClient.Reset() + stub := gowiremock.Delete(gowiremock.URLPathTemplate("/api/v1/objects/{objectPath}")).WithPathParam( + "objectPath", + gowiremock.Matching("objectPath"), + ).WillReturnResponse( + gowiremock.NewResponse().WithJSONBody( + map[string]interface{}{}, + ).WithStatus(http.StatusOK), + ) + err := WireMockClient.StubFor(stub) + require.NoError(t, err, "Failed to create WireMock stub") + + client := client.NewClient( + option.WithBaseURL( + WireMockBaseURL, + ), + ) + invocationErr := client.Objects.DeleteObject( + context.TODO(), + "objectPath", + ) + + require.NoError(t, invocationErr, "Client method call should succeed") + ok, countErr := WireMockClient.Verify(stub.Request(), 1) + require.NoError(t, countErr, "Failed to verify WireMock request was matched") + require.True(t, ok, "WireMock request was not matched") +} + +func TestObjectsGetObjectMetadataWithWireMock( + t *testing.T, +) { + // wiremock client and server initialized in shared main_test.go + defer WireMockClient.Reset() + stub := gowiremock.Head(gowiremock.URLPathTemplate("/api/v1/objects/{objectPath}")).WithPathParam( + "objectPath", + gowiremock.Matching("objectPath"), + ).WillReturnResponse( + gowiremock.NewResponse().WithJSONBody( + map[string]interface{}{}, + ).WithStatus(http.StatusOK), + ) + err := WireMockClient.StubFor(stub) + require.NoError(t, err, "Failed to create WireMock stub") + + client := client.NewClient( + option.WithBaseURL( + WireMockBaseURL, + ), + ) + invocationErr := client.Objects.GetObjectMetadata( + context.TODO(), + "objectPath", + ) + + require.NoError(t, invocationErr, "Client method call should succeed") + ok, countErr := WireMockClient.Verify(stub.Request(), 1) + require.NoError(t, countErr, "Failed to verify WireMock request was matched") + require.True(t, ok, "WireMock request was not matched") +} diff --git a/tasks/tasks_test/tasks_test.go b/tasks/tasks_test/tasks_test.go new file mode 100644 index 0000000..b446c2a --- /dev/null +++ b/tasks/tasks_test/tasks_test.go @@ -0,0 +1,282 @@ +// Code generated by Fern. DO NOT EDIT. + +package tasks_test + +import ( + context "context" + fmt "fmt" + v3 "github.com/anduril/lattice-sdk-go/v3" + client "github.com/anduril/lattice-sdk-go/v3/client" + option "github.com/anduril/lattice-sdk-go/v3/option" + require "github.com/stretchr/testify/require" + gowiremock "github.com/wiremock/go-wiremock" + wiremocktestcontainersgo "github.com/wiremock/wiremock-testcontainers-go" + http "net/http" + os "os" + testing "testing" +) + +// TestMain sets up shared test fixtures for all tests in this package// Global test fixtures +var ( + WireMockContainer *wiremocktestcontainersgo.WireMockContainer + WireMockBaseURL string + WireMockClient *gowiremock.Client +) + +// TestMain sets up shared test fixtures for all tests in this package +func TestMain(m *testing.M) { + // Setup shared WireMock container + ctx := context.Background() + container, err := wiremocktestcontainersgo.RunContainerAndStopOnCleanup( + ctx, + &testing.T{}, + wiremocktestcontainersgo.WithImage("docker.io/wiremock/wiremock:3.9.1"), + ) + if err != nil { + fmt.Printf("Failed to start WireMock container: %v\n", err) + os.Exit(1) + } + + // Store global references + WireMockContainer = container + + // Try to get the base URL using the standard method first + baseURL, err := container.Endpoint(ctx, "") + if err == nil { + // Standard method worked (running outside DinD) + // This uses the mapped port (e.g., localhost:59553) + WireMockBaseURL = "http://" + baseURL + WireMockClient = container.Client + } else { + // Standard method failed, use internal IP fallback (DinD environment) + fmt.Printf("Standard endpoint resolution failed, using internal IP fallback: %v\n", err) + + inspect, err := container.Inspect(ctx) + if err != nil { + fmt.Printf("Failed to inspect WireMock container: %v\n", err) + os.Exit(1) + } + + // Find the IP address from the container's networks + var containerIP string + for _, network := range inspect.NetworkSettings.Networks { + if network.IPAddress != "" { + containerIP = network.IPAddress + break + } + } + + if containerIP == "" { + fmt.Printf("Failed to get WireMock container IP address\n") + os.Exit(1) + } + + // In DinD, use the internal port directly (8080 for WireMock HTTP) + // Don't use the mapped port since it doesn't exist in this environment + WireMockBaseURL = fmt.Sprintf("http://%s:8080", containerIP) + + // The container.Client was created with a bad URL, so we need a new one + WireMockClient = gowiremock.NewClient(WireMockBaseURL) + } + + fmt.Printf("WireMock available at: %s\n", WireMockBaseURL) + + // Run all tests + code := m.Run() + + // Cleanup + if WireMockContainer != nil { + WireMockContainer.Terminate(ctx) + } + + // Exit with the same code as the tests + os.Exit(code) +} + +func TestTasksCreateTaskWithWireMock( + t *testing.T, +) { + // wiremock client and server initialized in shared main_test.go + defer WireMockClient.Reset() + stub := gowiremock.Post(gowiremock.URLPathTemplate("/api/v1/tasks")).WithBodyPattern(gowiremock.MatchesJsonSchema(`{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "required": [], + "properties": { + + }, + "additionalProperties": true + }`, "V202012")).WillReturnResponse( + gowiremock.NewResponse().WithJSONBody( + map[string]interface{}{"version": map[string]interface{}{"taskId": "taskId", "definitionVersion": 1, "statusVersion": 1}, "displayName": "displayName", "specification": map[string]interface{}{"@type": "@type"}, "createdBy": map[string]interface{}{"system": map[string]interface{}{"serviceName": "serviceName", "entityId": "entityId", "managesOwnScheduling": true}, "user": map[string]interface{}{"userId": "userId"}, "team": map[string]interface{}{"entityId": "entityId", "members": []interface{}{map[string]interface{}{}}}}, "lastUpdatedBy": map[string]interface{}{"system": map[string]interface{}{"serviceName": "serviceName", "entityId": "entityId", "managesOwnScheduling": true}, "user": map[string]interface{}{"userId": "userId"}, "team": map[string]interface{}{"entityId": "entityId", "members": []interface{}{map[string]interface{}{}}}}, "lastUpdateTime": "2024-01-15T09:30:00Z", "status": map[string]interface{}{"status": "STATUS_INVALID", "taskError": map[string]interface{}{"code": "ERROR_CODE_INVALID", "message": "message"}, "progress": map[string]interface{}{"@type": "@type"}, "result": map[string]interface{}{"@type": "@type"}, "startTime": "2024-01-15T09:30:00Z", "estimate": map[string]interface{}{"@type": "@type"}, "allocation": map[string]interface{}{"activeAgents": []interface{}{map[string]interface{}{}}}}, "scheduledTime": "2024-01-15T09:30:00Z", "relations": map[string]interface{}{"parentTaskId": "parentTaskId"}, "description": "description", "isExecutedElsewhere": true, "createTime": "2024-01-15T09:30:00Z", "replication": map[string]interface{}{"staleTime": "2024-01-15T09:30:00Z"}, "initialEntities": []interface{}{map[string]interface{}{"snapshot": true}}, "owner": map[string]interface{}{"entityId": "entityId"}}, + ).WithStatus(http.StatusOK), + ) + err := WireMockClient.StubFor(stub) + require.NoError(t, err, "Failed to create WireMock stub") + + client := client.NewClient( + option.WithBaseURL( + WireMockBaseURL, + ), + ) + request := &Lattice.TaskCreation{} + _, invocationErr := client.Tasks.CreateTask( + context.TODO(), + request, + ) + + require.NoError(t, invocationErr, "Client method call should succeed") + ok, countErr := WireMockClient.Verify(stub.Request(), 1) + require.NoError(t, countErr, "Failed to verify WireMock request was matched") + require.True(t, ok, "WireMock request was not matched") +} + +func TestTasksGetTaskWithWireMock( + t *testing.T, +) { + // wiremock client and server initialized in shared main_test.go + defer WireMockClient.Reset() + stub := gowiremock.Get(gowiremock.URLPathTemplate("/api/v1/tasks/{taskId}")).WithPathParam( + "taskId", + gowiremock.Matching("taskId"), + ).WillReturnResponse( + gowiremock.NewResponse().WithJSONBody( + map[string]interface{}{"version": map[string]interface{}{"taskId": "taskId", "definitionVersion": 1, "statusVersion": 1}, "displayName": "displayName", "specification": map[string]interface{}{"@type": "@type"}, "createdBy": map[string]interface{}{"system": map[string]interface{}{"serviceName": "serviceName", "entityId": "entityId", "managesOwnScheduling": true}, "user": map[string]interface{}{"userId": "userId"}, "team": map[string]interface{}{"entityId": "entityId", "members": []interface{}{map[string]interface{}{}}}}, "lastUpdatedBy": map[string]interface{}{"system": map[string]interface{}{"serviceName": "serviceName", "entityId": "entityId", "managesOwnScheduling": true}, "user": map[string]interface{}{"userId": "userId"}, "team": map[string]interface{}{"entityId": "entityId", "members": []interface{}{map[string]interface{}{}}}}, "lastUpdateTime": "2024-01-15T09:30:00Z", "status": map[string]interface{}{"status": "STATUS_INVALID", "taskError": map[string]interface{}{"code": "ERROR_CODE_INVALID", "message": "message"}, "progress": map[string]interface{}{"@type": "@type"}, "result": map[string]interface{}{"@type": "@type"}, "startTime": "2024-01-15T09:30:00Z", "estimate": map[string]interface{}{"@type": "@type"}, "allocation": map[string]interface{}{"activeAgents": []interface{}{map[string]interface{}{}}}}, "scheduledTime": "2024-01-15T09:30:00Z", "relations": map[string]interface{}{"parentTaskId": "parentTaskId"}, "description": "description", "isExecutedElsewhere": true, "createTime": "2024-01-15T09:30:00Z", "replication": map[string]interface{}{"staleTime": "2024-01-15T09:30:00Z"}, "initialEntities": []interface{}{map[string]interface{}{"snapshot": true}}, "owner": map[string]interface{}{"entityId": "entityId"}}, + ).WithStatus(http.StatusOK), + ) + err := WireMockClient.StubFor(stub) + require.NoError(t, err, "Failed to create WireMock stub") + + client := client.NewClient( + option.WithBaseURL( + WireMockBaseURL, + ), + ) + _, invocationErr := client.Tasks.GetTask( + context.TODO(), + "taskId", + ) + + require.NoError(t, invocationErr, "Client method call should succeed") + ok, countErr := WireMockClient.Verify(stub.Request(), 1) + require.NoError(t, countErr, "Failed to verify WireMock request was matched") + require.True(t, ok, "WireMock request was not matched") +} + +func TestTasksUpdateTaskStatusWithWireMock( + t *testing.T, +) { + // wiremock client and server initialized in shared main_test.go + defer WireMockClient.Reset() + stub := gowiremock.Put(gowiremock.URLPathTemplate("/api/v1/tasks/{taskId}/status")).WithPathParam( + "taskId", + gowiremock.Matching("taskId"), + ).WithBodyPattern(gowiremock.MatchesJsonSchema(`{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "required": [], + "properties": { + + }, + "additionalProperties": true + }`, "V202012")).WillReturnResponse( + gowiremock.NewResponse().WithJSONBody( + map[string]interface{}{"version": map[string]interface{}{"taskId": "taskId", "definitionVersion": 1, "statusVersion": 1}, "displayName": "displayName", "specification": map[string]interface{}{"@type": "@type"}, "createdBy": map[string]interface{}{"system": map[string]interface{}{"serviceName": "serviceName", "entityId": "entityId", "managesOwnScheduling": true}, "user": map[string]interface{}{"userId": "userId"}, "team": map[string]interface{}{"entityId": "entityId", "members": []interface{}{map[string]interface{}{}}}}, "lastUpdatedBy": map[string]interface{}{"system": map[string]interface{}{"serviceName": "serviceName", "entityId": "entityId", "managesOwnScheduling": true}, "user": map[string]interface{}{"userId": "userId"}, "team": map[string]interface{}{"entityId": "entityId", "members": []interface{}{map[string]interface{}{}}}}, "lastUpdateTime": "2024-01-15T09:30:00Z", "status": map[string]interface{}{"status": "STATUS_INVALID", "taskError": map[string]interface{}{"code": "ERROR_CODE_INVALID", "message": "message"}, "progress": map[string]interface{}{"@type": "@type"}, "result": map[string]interface{}{"@type": "@type"}, "startTime": "2024-01-15T09:30:00Z", "estimate": map[string]interface{}{"@type": "@type"}, "allocation": map[string]interface{}{"activeAgents": []interface{}{map[string]interface{}{}}}}, "scheduledTime": "2024-01-15T09:30:00Z", "relations": map[string]interface{}{"parentTaskId": "parentTaskId"}, "description": "description", "isExecutedElsewhere": true, "createTime": "2024-01-15T09:30:00Z", "replication": map[string]interface{}{"staleTime": "2024-01-15T09:30:00Z"}, "initialEntities": []interface{}{map[string]interface{}{"snapshot": true}}, "owner": map[string]interface{}{"entityId": "entityId"}}, + ).WithStatus(http.StatusOK), + ) + err := WireMockClient.StubFor(stub) + require.NoError(t, err, "Failed to create WireMock stub") + + client := client.NewClient( + option.WithBaseURL( + WireMockBaseURL, + ), + ) + request := &Lattice.TaskStatusUpdate{} + _, invocationErr := client.Tasks.UpdateTaskStatus( + context.TODO(), + "taskId", + request, + ) + + require.NoError(t, invocationErr, "Client method call should succeed") + ok, countErr := WireMockClient.Verify(stub.Request(), 1) + require.NoError(t, countErr, "Failed to verify WireMock request was matched") + require.True(t, ok, "WireMock request was not matched") +} + +func TestTasksQueryTasksWithWireMock( + t *testing.T, +) { + // wiremock client and server initialized in shared main_test.go + defer WireMockClient.Reset() + stub := gowiremock.Post(gowiremock.URLPathTemplate("/api/v1/tasks/query")).WithBodyPattern(gowiremock.MatchesJsonSchema(`{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "required": [], + "properties": { + + }, + "additionalProperties": true + }`, "V202012")).WillReturnResponse( + gowiremock.NewResponse().WithJSONBody( + map[string]interface{}{"tasks": []interface{}{map[string]interface{}{"displayName": "displayName", "lastUpdateTime": "2024-01-15T09:30:00Z", "scheduledTime": "2024-01-15T09:30:00Z", "description": "description", "isExecutedElsewhere": true, "createTime": "2024-01-15T09:30:00Z", "initialEntities": []interface{}{map[string]interface{}{}}}}, "nextPageToken": "nextPageToken"}, + ).WithStatus(http.StatusOK), + ) + err := WireMockClient.StubFor(stub) + require.NoError(t, err, "Failed to create WireMock stub") + + client := client.NewClient( + option.WithBaseURL( + WireMockBaseURL, + ), + ) + request := &Lattice.TaskQuery{} + _, invocationErr := client.Tasks.QueryTasks( + context.TODO(), + request, + ) + + require.NoError(t, invocationErr, "Client method call should succeed") + ok, countErr := WireMockClient.Verify(stub.Request(), 1) + require.NoError(t, countErr, "Failed to verify WireMock request was matched") + require.True(t, ok, "WireMock request was not matched") +} + +func TestTasksListenAsAgentWithWireMock( + t *testing.T, +) { + // wiremock client and server initialized in shared main_test.go + defer WireMockClient.Reset() + stub := gowiremock.Post(gowiremock.URLPathTemplate("/api/v1/agent/listen")).WithBodyPattern(gowiremock.MatchesJsonSchema(`{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "required": [], + "properties": { + + }, + "additionalProperties": true + }`, "V202012")).WillReturnResponse( + gowiremock.NewResponse().WithJSONBody( + map[string]interface{}{"executeRequest": map[string]interface{}{"task": map[string]interface{}{"displayName": "displayName", "lastUpdateTime": "2024-01-15T09:30:00Z", "scheduledTime": "2024-01-15T09:30:00Z", "description": "description", "isExecutedElsewhere": true, "createTime": "2024-01-15T09:30:00Z", "initialEntities": []interface{}{map[string]interface{}{}}}}, "cancelRequest": map[string]interface{}{"taskId": "taskId"}, "completeRequest": map[string]interface{}{"taskId": "taskId"}}, + ).WithStatus(http.StatusOK), + ) + err := WireMockClient.StubFor(stub) + require.NoError(t, err, "Failed to create WireMock stub") + + client := client.NewClient( + option.WithBaseURL( + WireMockBaseURL, + ), + ) + request := &Lattice.AgentListener{} + _, invocationErr := client.Tasks.ListenAsAgent( + context.TODO(), + request, + ) + + require.NoError(t, invocationErr, "Client method call should succeed") + ok, countErr := WireMockClient.Verify(stub.Request(), 1) + require.NoError(t, countErr, "Failed to verify WireMock request was matched") + require.True(t, ok, "WireMock request was not matched") +}