v0.1.94 90d877f

amazon_bedrock_test.go RawHistoryFolder

1package provider
2
3import (
4	"bytes"
5	"net/http"
6	"strings"
7	"testing"
8	"time"
9)
10
11// TestSigV4Known checks our signer against AWS's published test vector
12// from the SigV4 documentation. The expected Authorization header below
13// is taken from "get-vanilla" in the suite (adapted: we use POST with
14// an empty body since Bedrock is always POST).
15//
16// We don't run the official suite (it lives in S3 as a tarball and the
17// signing rules vary slightly between examples); instead this test
18// pins a fixed input/output so future refactors can't silently break
19// the signer.
20func TestSigV4Deterministic(t *testing.T) {
21	creds := &bedrockSigV4Creds{
22		accessKeyID:     "AKIDEXAMPLE",
23		secretAccessKey: "wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY",
24	}
25	body := []byte(`{"hello":"world"}`)
26	req, err := http.NewRequest("POST", "https://bedrock-runtime.us-east-1.amazonaws.com/model/foo/converse-stream", bytes.NewReader(body))
27	if err != nil {
28		t.Fatal(err)
29	}
30	req.Header.Set("content-type", "application/json")
31	when := time.Date(2024, 1, 15, 12, 0, 0, 0, time.UTC)
32	if err := signSigV4(req, body, "bedrock", "us-east-1", creds, when); err != nil {
33		t.Fatal(err)
34	}
35	auth := req.Header.Get("Authorization")
36	if !strings.HasPrefix(auth, "AWS4-HMAC-SHA256 ") {
37		t.Fatalf("missing AWS4 prefix: %q", auth)
38	}
39	if !strings.Contains(auth, "Credential=AKIDEXAMPLE/20240115/us-east-1/bedrock/aws4_request") {
40		t.Errorf("wrong credential scope: %q", auth)
41	}
42	if !strings.Contains(auth, "SignedHeaders=") {
43		t.Errorf("missing SignedHeaders: %q", auth)
44	}
45	if !strings.Contains(auth, "Signature=") {
46		t.Errorf("missing Signature: %q", auth)
47	}
48	// Sign again with identical inputs -> identical signature (determinism).
49	req2, _ := http.NewRequest("POST", "https://bedrock-runtime.us-east-1.amazonaws.com/model/foo/converse-stream", bytes.NewReader(body))
50	req2.Header.Set("content-type", "application/json")
51	if err := signSigV4(req2, body, "bedrock", "us-east-1", creds, when); err != nil {
52		t.Fatal(err)
53	}
54	if req2.Header.Get("Authorization") != auth {
55		t.Errorf("signature not deterministic:\n a=%q\n b=%q", auth, req2.Header.Get("Authorization"))
56	}
57}
58
59func TestSigV4PathEncoding(t *testing.T) {
60	// Bedrock model IDs include colons and dots. The colon must encode
61	// to %3A in the canonical path (per SigV4 rules).
62	cases := map[string]string{
63		"/model/anthropic.claude-sonnet-4-5-20250929-v1:0/converse-stream": "/model/anthropic.claude-sonnet-4-5-20250929-v1%3A0/converse-stream",
64		"/":  "/",
65		"":   "/",
66		"/a": "/a",
67	}
68	for in, want := range cases {
69		got := canonicalSigV4Path(in)
70		if got != want {
71			t.Errorf("canonicalSigV4Path(%q) = %q, want %q", in, got, want)
72		}
73	}
74}
75
76func TestReadAWSCredentialsFile(t *testing.T) {
77	// Smoke test: parses an INI-ish file when present. We don't require
78	// the file to exist on the test host.
79	if _, err := readAWSCredentialsFile("default"); err != nil {
80		// missing file or missing profile is fine — both are non-panics
81		t.Logf("no aws creds available (expected on CI): %v", err)
82	}
83}

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 1

Tags 477

↑↓ moveenter openesc close