Skip to content

Commit 8504e77

Browse files
committed
test: ClickHouse env detection + Filesystem chmod-on-ENOENT
Cover two gaps from the ClickHouse driver (#574) and the chmod fix: - detectEnvVars: CLICKHOUSE_HOST, CLICKHOUSE_URL, and DATABASE_URL scheme mapping - Filesystem.write: permissions applied correctly when parent dirs don't exist Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> https://claude.ai/code/session_01EzpUnoRYpyCw3EfdFBQ9jd
1 parent 0d34855 commit 8504e77

2 files changed

Lines changed: 80 additions & 0 deletions

File tree

packages/opencode/test/tool/project-scan.test.ts

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,8 @@ describe("detectEnvVars", () => {
312312
"PGHOST", "PGPORT", "PGDATABASE", "PGUSER", "PGPASSWORD", "DATABASE_URL",
313313
"MYSQL_HOST", "MYSQL_TCP_PORT", "MYSQL_DATABASE", "MYSQL_USER", "MYSQL_PASSWORD",
314314
"REDSHIFT_HOST", "REDSHIFT_PORT", "REDSHIFT_DATABASE", "REDSHIFT_USER", "REDSHIFT_PASSWORD",
315+
"CLICKHOUSE_HOST", "CLICKHOUSE_PORT", "CLICKHOUSE_DB", "CLICKHOUSE_DATABASE",
316+
"CLICKHOUSE_USER", "CLICKHOUSE_USERNAME", "CLICKHOUSE_PASSWORD", "CLICKHOUSE_URL",
315317
]
316318
for (const v of vars) {
317319
delete process.env[v]
@@ -554,6 +556,70 @@ describe("detectEnvVars", () => {
554556
expect(conn.name).toBe(`env_${conn.type}`)
555557
}
556558
})
559+
560+
test("detects ClickHouse via CLICKHOUSE_HOST", async () => {
561+
clearWarehouseEnvVars()
562+
process.env.CLICKHOUSE_HOST = "ch.example.com"
563+
process.env.CLICKHOUSE_PORT = "8443"
564+
process.env.CLICKHOUSE_DATABASE = "analytics"
565+
process.env.CLICKHOUSE_USER = "default"
566+
567+
const result = await detectEnvVars()
568+
const ch = result.find((r) => r.type === "clickhouse")
569+
expect(ch).toBeDefined()
570+
expect(ch!.name).toBe("env_clickhouse")
571+
expect(ch!.source).toBe("env-var")
572+
expect(ch!.signal).toBe("CLICKHOUSE_HOST")
573+
expect(ch!.config.host).toBe("ch.example.com")
574+
expect(ch!.config.port).toBe("8443")
575+
expect(ch!.config.database).toBe("analytics")
576+
expect(ch!.config.user).toBe("default")
577+
})
578+
579+
test("detects ClickHouse via CLICKHOUSE_URL (connection_string redacted)", async () => {
580+
clearWarehouseEnvVars()
581+
process.env.CLICKHOUSE_URL = "clickhouse://default:secret@ch.example.com:9000/analytics"
582+
583+
const result = await detectEnvVars()
584+
const ch = result.find((r) => r.type === "clickhouse")
585+
expect(ch).toBeDefined()
586+
expect(ch!.name).toBe("env_clickhouse")
587+
expect(ch!.signal).toBe("CLICKHOUSE_URL")
588+
// connection_string is a sensitive key — detectEnvVars redacts it to "***"
589+
expect(ch!.config.connection_string).toBe("***")
590+
})
591+
592+
test("detects ClickHouse via DATABASE_URL with clickhouse:// scheme", async () => {
593+
clearWarehouseEnvVars()
594+
process.env.DATABASE_URL = "clickhouse://default:pass@ch.example.com:9000/analytics"
595+
596+
const result = await detectEnvVars()
597+
const ch = result.find((r) => r.type === "clickhouse")
598+
expect(ch).toBeDefined()
599+
expect(ch!.name).toBe("env_clickhouse")
600+
expect(ch!.type).toBe("clickhouse")
601+
expect(ch!.signal).toBe("DATABASE_URL")
602+
})
603+
604+
test("detects ClickHouse via DATABASE_URL with clickhouse+http scheme", async () => {
605+
clearWarehouseEnvVars()
606+
process.env.DATABASE_URL = "clickhouse+http://default:pass@ch.example.com:8123/analytics"
607+
608+
const result = await detectEnvVars()
609+
const ch = result.find((r) => r.type === "clickhouse")
610+
expect(ch).toBeDefined()
611+
expect(ch!.type).toBe("clickhouse")
612+
})
613+
614+
test("detects ClickHouse via DATABASE_URL with clickhouse+https scheme", async () => {
615+
clearWarehouseEnvVars()
616+
process.env.DATABASE_URL = "clickhouse+https://default:pass@ch.example.com:8443/analytics"
617+
618+
const result = await detectEnvVars()
619+
const ch = result.find((r) => r.type === "clickhouse")
620+
expect(ch).toBeDefined()
621+
expect(ch!.type).toBe("clickhouse")
622+
})
557623
})
558624

559625
// ---------------------------------------------------------------------------

packages/opencode/test/util/filesystem.test.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,20 @@ describe("filesystem", () => {
217217

218218
expect(await fs.readFile(filepath, "utf-8")).toBe(content)
219219
})
220+
221+
test("creates parent directories with correct permissions", async () => {
222+
await using tmp = await tmpdir()
223+
const filepath = path.join(tmp.path, "nested", "deep", "secret.txt")
224+
const content = "secret data"
225+
226+
await Filesystem.write(filepath, content, 0o600)
227+
228+
expect(await fs.readFile(filepath, "utf-8")).toBe(content)
229+
if (process.platform !== "win32") {
230+
const stats = await fs.stat(filepath)
231+
expect(stats.mode & 0o777).toBe(0o600)
232+
}
233+
})
220234
})
221235

222236
describe("writeJson()", () => {

0 commit comments

Comments
 (0)