Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 68 additions & 0 deletions packages/opencode/test/altimate/connections.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,36 @@ describe("ConnectionRegistry", () => {
)
})

test("cassandra gives helpful hint instead of generic unsupported error", async () => {
Registry.setConfigs({
mydb: { type: "cassandra", host: "localhost" },
})
await expect(Registry.get("mydb")).rejects.toThrow("not yet supported")
await expect(Registry.get("mydb")).rejects.toThrow("cqlsh")
})

test("cockroachdb suggests using postgres type", async () => {
Registry.setConfigs({
mydb: { type: "cockroachdb", host: "localhost" },
})
await expect(Registry.get("mydb")).rejects.toThrow("postgres")
})

test("timescaledb suggests using postgres type", async () => {
Registry.setConfigs({
mydb: { type: "timescaledb", host: "localhost" },
})
await expect(Registry.get("mydb")).rejects.toThrow("postgres")
})

test("truly unknown type gives generic unsupported error with supported list", async () => {
Registry.setConfigs({
mydb: { type: "neo4j", host: "localhost" },
})
await expect(Registry.get("mydb")).rejects.toThrow("Unsupported database type")
await expect(Registry.get("mydb")).rejects.toThrow("Supported:")
})

test("getConfig returns config for known connection", () => {
Registry.setConfigs({
mydb: { type: "postgres", host: "localhost" },
Expand Down Expand Up @@ -608,6 +638,44 @@ trino_project:
fs.rmSync(tmpDir, { recursive: true })
}
})

test("clickhouse adapter maps correctly from dbt profiles", async () => {
const fs = await import("fs")
const os = await import("os")
const path = await import("path")

const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "dbt-test-"))
const profilesPath = path.join(tmpDir, "profiles.yml")

fs.writeFileSync(
profilesPath,
`
ch_project:
outputs:
dev:
type: clickhouse
host: clickhouse.example.com
port: 8443
user: default
password: secret
database: analytics
schema: default
`,
)

try {
const connections = await parseDbtProfiles(profilesPath)
expect(connections).toHaveLength(1)
expect(connections[0].type).toBe("clickhouse")
expect(connections[0].config.type).toBe("clickhouse")
expect(connections[0].config.host).toBe("clickhouse.example.com")
expect(connections[0].config.port).toBe(8443)
expect(connections[0].config.user).toBe("default")
expect(connections[0].config.database).toBe("analytics")
} finally {
fs.rmSync(tmpDir, { recursive: true })
}
})
})

// ---------------------------------------------------------------------------
Expand Down
47 changes: 47 additions & 0 deletions packages/opencode/test/altimate/schema-finops-dbt.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,53 @@ describe("FinOps: SQL template generation", () => {
const built = HistoryTemplates.buildHistoryQuery("databricks", 7, 50)
expect(built?.sql).toContain("system.query.history")
})

test("builds ClickHouse history SQL with clamped integer days and limit", () => {
const built = HistoryTemplates.buildHistoryQuery("clickhouse", 7, 100)
expect(built).not.toBeNull()
expect(built?.sql).toContain("system.query_log")
expect(built?.sql).toContain("QueryFinish")
// Days and limit should be integer-substituted, not bind params
expect(built?.binds).toEqual([])
// Verify the clamped values are in the SQL
expect(built?.sql).toContain("today() - 7")
expect(built?.sql).toContain("LIMIT 100")
})

test("ClickHouse buildHistoryQuery clamps extreme days and limit values", () => {
// Days clamped to [1, 365]
const extremeDays = HistoryTemplates.buildHistoryQuery("clickhouse", 9999, 50)
expect(extremeDays?.sql).toContain("today() - 365")

const zeroDays = HistoryTemplates.buildHistoryQuery("clickhouse", 0, 50)
// Math.floor(0) || 30 = 30 (0 is falsy), then Math.max(1, Math.min(30, 365)) = 30
expect(zeroDays?.sql).toContain("today() - 30")

// Limit clamped to [1, 10000]
const extremeLimit = HistoryTemplates.buildHistoryQuery("clickhouse", 7, 999999)
expect(extremeLimit?.sql).toContain("LIMIT 10000")

const zeroLimit = HistoryTemplates.buildHistoryQuery("clickhouse", 7, 0)
// Math.floor(0) || 100 = 100 (0 is falsy), then Math.max(1, Math.min(100, 10000)) = 100
expect(zeroLimit?.sql).toContain("LIMIT 100")
})

test("ClickHouse buildHistoryQuery handles NaN and float inputs safely", () => {
// NaN days defaults to 30 via || 30 fallback
const nanDays = HistoryTemplates.buildHistoryQuery("clickhouse", NaN, 50)
expect(nanDays?.sql).toContain("today() - 30")
expect(nanDays?.sql).not.toContain("NaN")

// NaN limit defaults to 100 via || 100 fallback
const nanLimit = HistoryTemplates.buildHistoryQuery("clickhouse", 7, NaN)
expect(nanLimit?.sql).toContain("LIMIT 100")
expect(nanLimit?.sql).not.toContain("NaN")

// Float values should be floored
const floatInputs = HistoryTemplates.buildHistoryQuery("clickhouse", 7.9, 50.5)
expect(floatInputs?.sql).toContain("today() - 7")
expect(floatInputs?.sql).toContain("LIMIT 50")
})
})

describe("warehouse-advisor", () => {
Expand Down
Loading