|
|
@@ -1,11 +1,40 @@
|
|
|
-import { test, expect } from "bun:test"
|
|
|
+import { test, expect, mock } from "bun:test"
|
|
|
import path from "path"
|
|
|
-import { tmpdir } from "../fixture/fixture"
|
|
|
-import { Instance } from "../../src/project/instance"
|
|
|
-import { Provider } from "../../src/provider/provider"
|
|
|
-import { Env } from "../../src/env"
|
|
|
-import { Auth } from "../../src/auth"
|
|
|
-import { Global } from "../../src/global"
|
|
|
+
|
|
|
+// === Mocks ===
|
|
|
+// These mocks are required because Provider.list() triggers:
|
|
|
+// 1. BunProc.install("@aws-sdk/credential-providers") - in bedrock custom loader
|
|
|
+// 2. Plugin.list() which calls BunProc.install() for default plugins
|
|
|
+// Without mocks, these would attempt real package installations that timeout in tests.
|
|
|
+
|
|
|
+mock.module("../../src/bun/index", () => ({
|
|
|
+ BunProc: {
|
|
|
+ install: async (pkg: string) => pkg,
|
|
|
+ run: async () => {
|
|
|
+ throw new Error("BunProc.run should not be called in tests")
|
|
|
+ },
|
|
|
+ which: () => process.execPath,
|
|
|
+ InstallFailedError: class extends Error {},
|
|
|
+ },
|
|
|
+}))
|
|
|
+
|
|
|
+mock.module("@aws-sdk/credential-providers", () => ({
|
|
|
+ fromNodeProviderChain: () => async () => ({
|
|
|
+ accessKeyId: "mock-access-key-id",
|
|
|
+ secretAccessKey: "mock-secret-access-key",
|
|
|
+ }),
|
|
|
+}))
|
|
|
+
|
|
|
+const mockPlugin = () => ({})
|
|
|
+mock.module("opencode-copilot-auth", () => ({ default: mockPlugin }))
|
|
|
+mock.module("opencode-anthropic-auth", () => ({ default: mockPlugin }))
|
|
|
+
|
|
|
+// Import after mocks are set up
|
|
|
+const { tmpdir } = await import("../fixture/fixture")
|
|
|
+const { Instance } = await import("../../src/project/instance")
|
|
|
+const { Provider } = await import("../../src/provider/provider")
|
|
|
+const { Env } = await import("../../src/env")
|
|
|
+const { Global } = await import("../../src/global")
|
|
|
|
|
|
test("Bedrock: config region takes precedence over AWS_REGION env var", async () => {
|
|
|
await using tmp = await tmpdir({
|
|
|
@@ -34,13 +63,12 @@ test("Bedrock: config region takes precedence over AWS_REGION env var", async ()
|
|
|
fn: async () => {
|
|
|
const providers = await Provider.list()
|
|
|
expect(providers["amazon-bedrock"]).toBeDefined()
|
|
|
- // Region from config should be used (not env var)
|
|
|
expect(providers["amazon-bedrock"].options?.region).toBe("eu-west-1")
|
|
|
},
|
|
|
})
|
|
|
})
|
|
|
|
|
|
-test("Bedrock: falls back to AWS_REGION env var when no config", async () => {
|
|
|
+test("Bedrock: falls back to AWS_REGION env var when no config region", async () => {
|
|
|
await using tmp = await tmpdir({
|
|
|
init: async (dir) => {
|
|
|
await Bun.write(
|
|
|
@@ -65,34 +93,7 @@ test("Bedrock: falls back to AWS_REGION env var when no config", async () => {
|
|
|
})
|
|
|
})
|
|
|
|
|
|
-test("Bedrock: without explicit region config, uses AWS_REGION env or defaults", async () => {
|
|
|
- await using tmp = await tmpdir({
|
|
|
- init: async (dir) => {
|
|
|
- await Bun.write(
|
|
|
- path.join(dir, "opencode.json"),
|
|
|
- JSON.stringify({
|
|
|
- $schema: "https://opencode.ai/config.json",
|
|
|
- }),
|
|
|
- )
|
|
|
- },
|
|
|
- })
|
|
|
- await Instance.provide({
|
|
|
- directory: tmp.path,
|
|
|
- init: async () => {
|
|
|
- Env.set("AWS_PROFILE", "default")
|
|
|
- // AWS_REGION might be set in the environment, use that or default
|
|
|
- },
|
|
|
- fn: async () => {
|
|
|
- const providers = await Provider.list()
|
|
|
- expect(providers["amazon-bedrock"]).toBeDefined()
|
|
|
- // Should have some region set (either from env or default)
|
|
|
- expect(providers["amazon-bedrock"].options?.region).toBeDefined()
|
|
|
- expect(typeof providers["amazon-bedrock"].options?.region).toBe("string")
|
|
|
- },
|
|
|
- })
|
|
|
-})
|
|
|
-
|
|
|
-test("Bedrock: uses config region in provider options", async () => {
|
|
|
+test("Bedrock: loads when bearer token from auth.json is present", async () => {
|
|
|
await using tmp = await tmpdir({
|
|
|
init: async (dir) => {
|
|
|
await Bun.write(
|
|
|
@@ -102,7 +103,7 @@ test("Bedrock: uses config region in provider options", async () => {
|
|
|
provider: {
|
|
|
"amazon-bedrock": {
|
|
|
options: {
|
|
|
- region: "eu-north-1",
|
|
|
+ region: "eu-west-1",
|
|
|
},
|
|
|
},
|
|
|
},
|
|
|
@@ -110,54 +111,35 @@ test("Bedrock: uses config region in provider options", async () => {
|
|
|
)
|
|
|
},
|
|
|
})
|
|
|
+
|
|
|
+ const authPath = path.join(Global.Path.data, "auth.json")
|
|
|
+ await Bun.write(
|
|
|
+ authPath,
|
|
|
+ JSON.stringify({
|
|
|
+ "amazon-bedrock": {
|
|
|
+ type: "api",
|
|
|
+ key: "test-bearer-token",
|
|
|
+ },
|
|
|
+ }),
|
|
|
+ )
|
|
|
+
|
|
|
await Instance.provide({
|
|
|
directory: tmp.path,
|
|
|
init: async () => {
|
|
|
- Env.set("AWS_PROFILE", "default")
|
|
|
+ Env.set("AWS_PROFILE", "")
|
|
|
+ Env.set("AWS_ACCESS_KEY_ID", "")
|
|
|
+ Env.set("AWS_BEARER_TOKEN_BEDROCK", "")
|
|
|
},
|
|
|
fn: async () => {
|
|
|
const providers = await Provider.list()
|
|
|
- const bedrockProvider = providers["amazon-bedrock"]
|
|
|
- expect(bedrockProvider).toBeDefined()
|
|
|
- expect(bedrockProvider.options?.region).toBe("eu-north-1")
|
|
|
+ expect(providers["amazon-bedrock"]).toBeDefined()
|
|
|
+ expect(providers["amazon-bedrock"].options?.region).toBe("eu-west-1")
|
|
|
},
|
|
|
})
|
|
|
})
|
|
|
|
|
|
-test("Bedrock: respects config region for different instances", async () => {
|
|
|
- // First instance with EU config
|
|
|
- await using tmp1 = await tmpdir({
|
|
|
- init: async (dir) => {
|
|
|
- await Bun.write(
|
|
|
- path.join(dir, "opencode.json"),
|
|
|
- JSON.stringify({
|
|
|
- $schema: "https://opencode.ai/config.json",
|
|
|
- provider: {
|
|
|
- "amazon-bedrock": {
|
|
|
- options: {
|
|
|
- region: "eu-west-1",
|
|
|
- },
|
|
|
- },
|
|
|
- },
|
|
|
- }),
|
|
|
- )
|
|
|
- },
|
|
|
- })
|
|
|
-
|
|
|
- await Instance.provide({
|
|
|
- directory: tmp1.path,
|
|
|
- init: async () => {
|
|
|
- Env.set("AWS_PROFILE", "default")
|
|
|
- Env.set("AWS_REGION", "us-east-1")
|
|
|
- },
|
|
|
- fn: async () => {
|
|
|
- const providers1 = await Provider.list()
|
|
|
- expect(providers1["amazon-bedrock"].options?.region).toBe("eu-west-1")
|
|
|
- },
|
|
|
- })
|
|
|
-
|
|
|
- // Second instance with US config
|
|
|
- await using tmp2 = await tmpdir({
|
|
|
+test("Bedrock: config profile takes precedence over AWS_PROFILE env var", async () => {
|
|
|
+ await using tmp = await tmpdir({
|
|
|
init: async (dir) => {
|
|
|
await Bun.write(
|
|
|
path.join(dir, "opencode.json"),
|
|
|
@@ -166,7 +148,8 @@ test("Bedrock: respects config region for different instances", async () => {
|
|
|
provider: {
|
|
|
"amazon-bedrock": {
|
|
|
options: {
|
|
|
- region: "us-west-2",
|
|
|
+ profile: "my-custom-profile",
|
|
|
+ region: "us-east-1",
|
|
|
},
|
|
|
},
|
|
|
},
|
|
|
@@ -174,21 +157,21 @@ test("Bedrock: respects config region for different instances", async () => {
|
|
|
)
|
|
|
},
|
|
|
})
|
|
|
-
|
|
|
await Instance.provide({
|
|
|
- directory: tmp2.path,
|
|
|
+ directory: tmp.path,
|
|
|
init: async () => {
|
|
|
Env.set("AWS_PROFILE", "default")
|
|
|
- Env.set("AWS_REGION", "eu-west-1")
|
|
|
+ Env.set("AWS_ACCESS_KEY_ID", "test-key-id")
|
|
|
},
|
|
|
fn: async () => {
|
|
|
- const providers2 = await Provider.list()
|
|
|
- expect(providers2["amazon-bedrock"].options?.region).toBe("us-west-2")
|
|
|
+ const providers = await Provider.list()
|
|
|
+ expect(providers["amazon-bedrock"]).toBeDefined()
|
|
|
+ expect(providers["amazon-bedrock"].options?.region).toBe("us-east-1")
|
|
|
},
|
|
|
})
|
|
|
})
|
|
|
|
|
|
-test("Bedrock: loads when bearer token from auth.json is present", async () => {
|
|
|
+test("Bedrock: includes custom endpoint in options when specified", async () => {
|
|
|
await using tmp = await tmpdir({
|
|
|
init: async (dir) => {
|
|
|
await Bun.write(
|
|
|
@@ -198,7 +181,7 @@ test("Bedrock: loads when bearer token from auth.json is present", async () => {
|
|
|
provider: {
|
|
|
"amazon-bedrock": {
|
|
|
options: {
|
|
|
- region: "eu-west-1",
|
|
|
+ endpoint: "https://bedrock-runtime.us-east-1.vpce-xxxxx.amazonaws.com",
|
|
|
},
|
|
|
},
|
|
|
},
|
|
|
@@ -206,31 +189,17 @@ test("Bedrock: loads when bearer token from auth.json is present", async () => {
|
|
|
)
|
|
|
},
|
|
|
})
|
|
|
-
|
|
|
- // Setup auth.json with bearer token for amazon-bedrock
|
|
|
- const authPath = path.join(Global.Path.data, "auth.json")
|
|
|
- await Bun.write(
|
|
|
- authPath,
|
|
|
- JSON.stringify({
|
|
|
- "amazon-bedrock": {
|
|
|
- type: "api",
|
|
|
- key: "test-bearer-token",
|
|
|
- },
|
|
|
- }),
|
|
|
- )
|
|
|
-
|
|
|
await Instance.provide({
|
|
|
directory: tmp.path,
|
|
|
init: async () => {
|
|
|
- // Clear env vars so only auth.json should trigger autoload
|
|
|
- Env.set("AWS_PROFILE", "")
|
|
|
- Env.set("AWS_ACCESS_KEY_ID", "")
|
|
|
- Env.set("AWS_BEARER_TOKEN_BEDROCK", "")
|
|
|
+ Env.set("AWS_PROFILE", "default")
|
|
|
},
|
|
|
fn: async () => {
|
|
|
const providers = await Provider.list()
|
|
|
expect(providers["amazon-bedrock"]).toBeDefined()
|
|
|
- expect(providers["amazon-bedrock"].options?.region).toBe("eu-west-1")
|
|
|
+ expect(providers["amazon-bedrock"].options?.endpoint).toBe(
|
|
|
+ "https://bedrock-runtime.us-east-1.vpce-xxxxx.amazonaws.com",
|
|
|
+ )
|
|
|
},
|
|
|
})
|
|
|
})
|