Beispiel
google.golang.org/appengine v1.2.0: APICall
Verifiziertes Beispiel für golang google.golang.org/appengine v1.2.0: APICall. Der Vertrag lief auf go 1.26 · linux debian/x64 · docker und bestand.
sha256:04aec383d1776a352bfb8925fb7d34728cfcf1138875b6a4e789d3a0e4fe6c06
Dieses Netzwerk bietet eine Sache: ein Sample, das baut. Es hat es in einer Sandbox ausgeführt und die signierte Quittung behalten. Es bewertet nichts und garantiert nichts — ob derselbe Code bei Ihnen baut, hat es nicht gemessen.
Wie viele verschiedene Signaturschlüssel eine bestandene Vertragsquittung eingereicht haben. Einer ist der Autor allein; mehr als einer heißt, jemand anderes hat es auch gebaut. Ein Schlüssel wird selbst erzeugt und hat keine registrierte Identität dahinter — gezählt werden Schlüssel, nicht Personen.
MIT-0
Ausführungsbelege
Die deklarierte Umgebung und die signierten Läufe stehen getrennt, damit Sie genau sehen, was dieses Sample ausgeführt hat und wo.
- Beleggrundlage
- Signierter Vertrag bestanden
- Verifizierungsbelege
- 1
- Signaturschlüssel, die es gebaut haben
- 1
Deklarierte Umgebung
linux 24 · ubuntu · glibc 2.39 x64 go
Umgebungen der Verifizierungsläufe
| Umgebung | Contract | Stufen | Lauf |
|---|---|---|---|
| go 1.26 · linux debian/x64 · docker ed25519:c1973797be207ac4 | PASS | compile:SKIPPED · contract:PASS · load:PASS · resolve:PASS CONTAINER_RUN · golang@1golang:1.26@sha256:e30143be198a… |
2026-10-17 |
Fall
HOW- Ziel
- verify google.golang.org/appengine.APICall in pkg:golang/google.golang.org/appengine@v1.2.0
- Symbole
-
- google.golang.org/appengine.APICall
- Erstellt
- 2026-10-17T21:49:36Z
Contract
- Calling appengine.APICall(ctx, service, method, in, out) on a plain non-App Engine context.Background() returns an error with message "not an App Engine context".
- Calling appengine.APICall(ctx, service, method, in, out) on an already-canceled context returns context.Canceled.
- Calling appengine.APICall(ctx, service, method, in, out) with an App Engine context (such as appengine.BackgroundContext()) marshals the input proto.Message into a RemoteAPI Request POST to /rpc_http and unmarshals the Response payload into the output proto.Message.
- Calling appengine.APICall on a context wrapped with appengine.WithAPICallFunc pops and invokes the registered APICallFunc override.
- When the RemoteAPI bridge returns an RpcError with OVER_QUOTA (code 4), appengine.APICall returns an error for which appengine.IsOverQuota(err) is true.
Dateien
- PROMPT.md
- csx.json
- go.mod
- go.sum
- spec.json
- test/contract.go
Quelltext
Clean-room public code sample — generation instructions
Write a brand-new, minimal, self-contained code sample in this clean-room directory.
Do not copy, paraphrase, or reference any existing project source. Work only from this spec.
A csx.json manifest scaffold already exists. Do not recreate it from memory. Preserve its case.goal, packages and symbols; fill its empty case.contract with exact assertions and correct its environment, commands and verifierAdapter for the files you generate.
Goal: verify google.golang.org/appengine.APICall in pkg:golang/google.golang.org/appengine@v1.2.0
Kind: HOW
Use EXACTLY these public packages and versions:
- pkg:golang/google.golang.org/appengine@v1.2.0
Demonstrate these symbols/APIs:
- google.golang.org/appengine.APICall
Rules:
- One focused purpose; the smallest project that proves the goal.
- Include a contract test (test/contract.*) that runs OFFLINE and exits 0 exactly when the goal behavior works.
- Pin every dependency with a lockfile so resolution is reproducible.
- No secrets, credentials, or tokens. No real URLs (only example.com or localhost). No absolute paths.
- No personal names, emails, company names, or project identifiers of any kind.
- No binaries and no generated output (node_modules, dist, target, venv, .git, .env).
- Keep it under 200 files and 256KB packed.
{"case":{"caseId":"case:sha256:77b5605924a1ccd1ee30879093691cd07088c11ac1c928a57883a1faaf014f13","contract":["Calling appengine.APICall(ctx, service, method, in, out) on a plain non-App Engine context.Background() returns an error with message \"not an App Engine context\".","Calling appengine.APICall(ctx, service, method, in, out) on an already-canceled context returns context.Canceled.","Calling appengine.APICall(ctx, service, method, in, out) with an App Engine context (such as appengine.BackgroundContext()) marshals the input proto.Message into a RemoteAPI Request POST to /rpc_http and unmarshals the Response payload into the output proto.Message.","Calling appengine.APICall on a context wrapped with appengine.WithAPICallFunc pops and invokes the registered APICallFunc override.","When the RemoteAPI bridge returns an RpcError with OVER_QUOTA (code 4), appengine.APICall returns an error for which appengine.IsOverQuota(err) is true."],"goal":"verify google.golang.org/appengine.APICall in pkg:golang/google.golang.org/appengine@v1.2.0","kind":"HOW","packages":["pkg:golang/google.golang.org/appengine@v1.2.0"],"schemaVersion":1,"symbols":["google.golang.org/appengine.APICall"]},"contractCommand":["go","run","./test"],"environment":{"arch":"x64","distro":"ubuntu","ecosystem":"golang","libc":"glibc","libcVersion":"2.39","os":"linux","osVersionBucket":"24","packageManager":"go","schemaVersion":1},"license":"MIT-0","packages":["pkg:golang/google.golang.org/appengine@v1.2.0"],"schemaVersion":1,"subject":"pkg:golang/google.golang.org/appengine@v1.2.0","symbols":["google.golang.org/appengine.APICall"],"verifierAdapter":"golang@1"}
module example.com/sample
go 1.26.0
require google.golang.org/appengine v1.2.0
require (
github.com/golang/protobuf v1.2.0 // indirect
golang.org/x/net v0.0.0-20180724234803-3673e40ba225 // indirect
golang.org/x/sync v0.24.0 // indirect
)
github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225 h1:kNX+jCowfMYzvlSvJu5pQWEmyWFrBXJ3PBy10xKMXK8=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/sync v0.24.0 h1:iqiDrGoDgyuvAKrhLQthUEzU/R378N78gXbBjxed7oA=
golang.org/x/sync v0.24.0/go.mod h1:sUUOizhqBxiL6pEWpqNLUiaJn1ShEbZ6BBqskPbjZm0=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
google.golang.org/appengine v1.2.0 h1:S0iUepdCWODXRvtE+gcRDd15L+k+k1AiHlMiMjefH24=
google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
{
"schemaVersion": 1,
"goal": "verify google.golang.org/appengine.APICall in pkg:golang/google.golang.org/appengine@v1.2.0",
"kind": "HOW",
"packages": [
"pkg:golang/google.golang.org/appengine@v1.2.0"
],
"symbols": [
"google.golang.org/appengine.APICall"
]
}
package main
import (
"bytes"
"context"
"errors"
"fmt"
"io"
"net"
"net/http"
"net/http/httptest"
"os"
"strings"
"google.golang.org/appengine"
)
type rpcMessage struct {
Value string `protobuf:"bytes,1,opt,name=value,proto3"`
}
func (m *rpcMessage) Reset() { *m = rpcMessage{} }
func (m *rpcMessage) String() string { return m.Value }
func (m *rpcMessage) ProtoMessage() {}
func fail(format string, args ...any) {
fmt.Fprintf(os.Stderr, format+"\n", args...)
os.Exit(1)
}
func main() {
// 1. Calling APICall on a plain non-App Engine context returns "not an App Engine context".
plainCtx := context.Background()
err := appengine.APICall(plainCtx, "testservice", "Echo", &rpcMessage{Value: "hello"}, &rpcMessage{})
if err == nil || err.Error() != "not an App Engine context" {
fail("expected 'not an App Engine context' error, got: %v", err)
}
// 2. Calling APICall on an already-canceled context returns context.Canceled.
canceledCtx, cancel := context.WithCancel(plainCtx)
cancel()
if err := appengine.APICall(canceledCtx, "testservice", "Echo", &rpcMessage{}, &rpcMessage{}); !errors.Is(err, context.Canceled) {
fail("expected context.Canceled, got: %v", err)
}
// 3. End-to-end APICall over local App Engine API bridge using BackgroundContext.
var gotPath, gotEndpoint, gotMethodHdr string
var gotBody []byte
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
gotPath = r.URL.Path
gotEndpoint = r.Header.Get("X-Google-Rpc-Service-Endpoint")
gotMethodHdr = r.Header.Get("X-Google-Rpc-Service-Method")
body, readErr := io.ReadAll(r.Body)
if readErr != nil {
http.Error(w, readErr.Error(), http.StatusInternalServerError)
return
}
gotBody = body
if bytes.Contains(body, []byte("OverQuotaMethod")) {
// remotepb.Response{RpcError: &remotepb.RpcError{Code: 4 (OVER_QUOTA), Detail: "quota"}}
rpcErrPayload := []byte{0x08, 0x04, 0x12, 0x05, 'q', 'u', 'o', 't', 'a'}
resp := append([]byte{0x2a, byte(len(rpcErrPayload))}, rpcErrPayload...)
w.Write(resp)
return
}
// Encode rpcMessage{Value: "pong"} -> field 1 (tag 0x0a), length 4, "pong"
inner := []byte{0x0a, 0x04, 'p', 'o', 'n', 'g'}
// Wrap in remotepb.Response{Response: inner} -> field 1 (tag 0x0a)
resp := append([]byte{0x0a, byte(len(inner))}, inner...)
w.Write(resp)
}))
defer srv.Close()
host, port, splitErr := net.SplitHostPort(srv.Listener.Addr().String())
if splitErr != nil {
fail("SplitHostPort failed: %v", splitErr)
}
os.Setenv("API_HOST", host)
os.Setenv("API_PORT", port)
os.Setenv("GAE_LONG_APP_ID", "sample-app")
os.Setenv("GAE_MINOR_VERSION", "1")
os.Setenv("GAE_MODULE_INSTANCE", "0")
os.Setenv("GAE_MODULE_NAME", "default")
os.Setenv("GAE_MODULE_VERSION", "v1")
aeCtx := appengine.BackgroundContext()
inMsg := &rpcMessage{Value: "ping"}
outMsg := &rpcMessage{}
if err := appengine.APICall(aeCtx, "actordb", "LookupActor", inMsg, outMsg); err != nil {
fail("APICall failed: %v", err)
}
if gotPath != "/rpc_http" {
fail("unexpected request path: got %q, want %q", gotPath, "/rpc_http")
}
if gotEndpoint != "app-engine-apis" {
fail("unexpected RPC endpoint header: got %q, want %q", gotEndpoint, "app-engine-apis")
}
if gotMethodHdr != "/VMRemoteAPI.CallRemoteAPI" {
fail("unexpected RPC method header: got %q, want %q", gotMethodHdr, "/VMRemoteAPI.CallRemoteAPI")
}
if !bytes.Contains(gotBody, []byte("actordb")) || !bytes.Contains(gotBody, []byte("LookupActor")) || !bytes.Contains(gotBody, []byte("ping")) {
fail("marshaled RemoteAPI request missing expected service/method/input payload: %x", gotBody)
}
if outMsg.Value != "pong" {
fail("unexpected unmarshaled response Value: got %q, want %q", outMsg.Value, "pong")
}
// 4. APICall with WithAPICallFunc pops the registered APICallFunc override and delegates execution.
overrideCtx := appengine.WithAPICallFunc(aeCtx, appengine.APICall)
overrideOut := &rpcMessage{}
if err := appengine.APICall(overrideCtx, "actordb", "LookupActor", inMsg, overrideOut); err != nil {
fail("APICall with WithAPICallFunc failed: %v", err)
}
if overrideOut.Value != "pong" {
fail("unexpected override response Value: got %q, want %q", overrideOut.Value, "pong")
}
// 5. APICall surfaces RpcError responses (such as OVER_QUOTA) from the bridge.
err = appengine.APICall(aeCtx, "actordb", "OverQuotaMethod", &rpcMessage{Value: "ping"}, &rpcMessage{})
if err == nil || !appengine.IsOverQuota(err) || !strings.Contains(err.Error(), "quota") {
fail("expected over-quota error from APICall, got: %v", err)
}
}
Ursprungs-Seeder
anonym