test-proxy-environment.ts 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. /**
  2. * Remove the machine's proxy configuration from every Vitest process.
  3. *
  4. * A developer's Clash and a CI runner's squid both export `HTTP_PROXY` and its siblings. Now that
  5. * the harness honors them, an ambient value silently decides test outcomes: a request meant for a
  6. * local fixture server is sent to a proxy that cannot resolve the fixture's hostname, and the
  7. * proxy's error page is recorded as the expected output. The same value also stands in for "what
  8. * the user exported" in any assertion about inherited proxy names.
  9. *
  10. * Clearing here gives every suite one known starting environment, so a test that needs a proxy sets
  11. * exactly the names it means to exercise. Suites that spawn a real `dsh` still clear the child's
  12. * environment themselves — they must hold whether or not a Vitest setup ran.
  13. *
  14. * One name resists this: `NODE_USE_ENV_PROXY`. Node samples the proxy environment when the process
  15. * starts, so deleting the variable from a setup file cannot unbind the built-in `fetch` it already
  16. * configured. A shell that exports it must unset it before running the suite. The names a proxy
  17. * application or a corporate profile actually exports — the eight below — are fully handled, because
  18. * only this repository's own resolver reads them and it runs after this.
  19. *
  20. * Real-API e2e is cleared too. Before proxy support existed every request connected directly and
  21. * that suite passed, so a direct connection is the environment it is known to work in; leaving the
  22. * ambient proxy in place would newly stake it on the proxy reaching the provider.
  23. * @module
  24. */
  25. import { globSync } from 'node:fs'
  26. import { resolve } from 'node:path'
  27. import { PROXY_ENV_NAMES } from '../packages/util/http-proxy/src/policy.ts'
  28. /** The flag a Node process reads before honoring the names above; ambient in the same way. */
  29. const NODE_PROXY_FLAG = 'NODE_USE_ENV_PROXY'
  30. /** This module's path as a `setupFiles` entry, so its own wiring test names it once. */
  31. export const TEST_PROXY_SETUP_FILE = './scripts/test-proxy-environment.ts'
  32. /**
  33. * Every Vitest configuration in the repository, discovered rather than listed: the web suites carry
  34. * no `setupFiles` today, and a hand-written list would let one of them gain a setup without gaining
  35. * this one. The wiring test asserts only over the configurations that declare a setup at all.
  36. *
  37. * @returns repository-relative config paths, sorted.
  38. */
  39. export function vitestConfigFiles(): string[] {
  40. return globSync('vitest*.ts', { cwd: resolve(import.meta.dirname, '..') }).sort()
  41. }
  42. /**
  43. * Delete every proxy name from one environment.
  44. *
  45. * @param env - the environment to clear.
  46. * @returns the names that carried a value, in the order checked.
  47. */
  48. export function clearAmbientProxyEnv(env: NodeJS.ProcessEnv): string[] {
  49. const cleared: string[] = []
  50. for (const name of [...PROXY_ENV_NAMES, NODE_PROXY_FLAG]) {
  51. if (env[name] === undefined) continue
  52. cleared.push(name)
  53. Reflect.deleteProperty(env, name)
  54. }
  55. return cleared
  56. }
  57. clearAmbientProxyEnv(process.env)