Skip to content

Add FDC Integration Tests #8703

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 34 commits into from
Jan 14, 2025
Merged
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
d6d2aaf
First pass at getting fdc tests to work
maneesht Jan 11, 2025
8b45245
Fixed formatting
maneesht Jan 11, 2025
200a2c8
Added logging
maneesht Jan 11, 2025
f4fbfba
Updated formatting
maneesht Jan 11, 2025
72de503
Fixed firebase integration action
maneesht Jan 11, 2025
d8603d6
configure password
maneesht Jan 11, 2025
2420317
log POSTGRES_PASSWORD
maneesht Jan 11, 2025
1abbe54
Fixed integration tests
maneesht Jan 13, 2025
50d074f
Fixed more integration
maneesht Jan 13, 2025
d62d264
Updated ignored tests
maneesht Jan 13, 2025
3225eda
Renamed job
maneesht Jan 13, 2025
244464a
Updated test config
maneesht Jan 13, 2025
4c96d8c
Fixed integration tests?
maneesht Jan 13, 2025
1391cc8
Ignored fdc
maneesht Jan 13, 2025
b224296
Updated ports
maneesht Jan 13, 2025
5ec4c4f
Updated formatting
maneesht Jan 13, 2025
13b490c
Updated changed yaml
maneesht Jan 13, 2025
7d03de6
Fixed failed test
maneesht Jan 13, 2025
f3a5bb4
Updated queries
maneesht Jan 13, 2025
8d71140
Fix testing
maneesht Jan 13, 2025
bffe9dd
Fix emulator port
maneesht Jan 13, 2025
e3848e8
Updated readme and logging
maneesht Jan 13, 2025
b1dfea9
Removed single run
maneesht Jan 13, 2025
46a4c40
Added more logging
maneesht Jan 13, 2025
4737466
Trigger Build
maneesht Jan 13, 2025
699a700
Fixed CI tests
maneesht Jan 14, 2025
cc03960
Added test IDs
maneesht Jan 14, 2025
4c45262
Updated yml
maneesht Jan 14, 2025
338f970
Addressed comments'
maneesht Jan 14, 2025
b5a8c4e
Removed console.logs
maneesht Jan 14, 2025
74e296e
Fixed formatting
maneesht Jan 14, 2025
74e970d
Addressed comments
maneesht Jan 14, 2025
bac7e1c
Removed unnecessary connection string
maneesht Jan 14, 2025
80e4ff0
Updated emualtor configs
maneesht Jan 14, 2025
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
2 changes: 1 addition & 1 deletion .github/workflows/test-firebase-integration.yml
Original file line number Diff line number Diff line change
@@ -46,4 +46,4 @@ jobs:
- name: build
run: yarn build:changed firebase-integration
- name: Run tests on changed packages
run: yarn test:changed firebase-integration
run: yarn test:changed firebase-integration
5 changes: 5 additions & 0 deletions packages/data-connect/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Firebase Data Connect

## Local Development

Check `test/dataconnect.yaml` to ensure that the correct values are filled in.
8 changes: 4 additions & 4 deletions packages/data-connect/package.json
Original file line number Diff line number Diff line change
@@ -31,10 +31,10 @@
"prettier": "prettier --write '*.js' '*.ts' '@(src|test)/**/*.ts'",
"build:deps": "lerna run --scope @firebase/'{app,data-connect}' --include-dependencies build",
"dev": "rollup -c -w",
"test": "run-p --npm-path npm test:emulator",
"test:ci": "node ../../scripts/run_tests_in_ci.js -s test:emulator",
"test:all": "run-p --npm-path npm lint test:unit",
"test:browser": "karma start --single-run",
"test": "run-p --npm-path npm lint test:emulator",
"test:ci": "node ../../scripts/run_tests_in_ci.js -s test:all",
"test:all": "run-p --npm-path npm lint test:browser test:node",
"test:browser": "karma start",
"test:node": "TS_NODE_FILES=true TS_NODE_CACHE=NO TS_NODE_COMPILER_OPTIONS='{\"module\":\"commonjs\"}' nyc --reporter lcovonly -- mocha 'test/{,!(browser)/**/}*.test.ts' --file src/index.node.ts --config ../../config/mocharc.node.js",
"test:unit": "TS_NODE_FILES=true TS_NODE_CACHE=NO TS_NODE_COMPILER_OPTIONS='{\"module\":\"commonjs\"}' nyc --reporter lcovonly -- mocha 'test/unit/**/*.test.ts' --file src/index.node.ts --config ../../config/mocharc.node.js",
"test:emulator": "ts-node --compiler-options='{\"module\":\"commonjs\"}' ../../scripts/emulator-testing/dataconnect-test-runner.ts",
2 changes: 1 addition & 1 deletion packages/data-connect/src/api/query.ts
Original file line number Diff line number Diff line change
@@ -124,7 +124,7 @@ export function queryRef<Data, Variables>(
dataConnect: dcInstance,
refType: QUERY_STR,
name: queryName,
variables: variables
variables
};
}
/**
1 change: 1 addition & 0 deletions packages/data-connect/src/network/transport/rest.ts
Original file line number Diff line number Diff line change
@@ -166,6 +166,7 @@ export class RESTTransport implements DataConnectTransport {
body: U
) => {
const abortController = new AbortController();

// TODO(mtewani): Update to proper value
const withAuth = this.withRetry(() =>
dcFetch<T, U>(
5 changes: 5 additions & 0 deletions packages/data-connect/test/.firebaserc
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"projects": {
"default": "jscore-sandbox-141b5"
}
}
69 changes: 69 additions & 0 deletions packages/data-connect/test/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
firebase-debug.log*
firebase-debug.*.log*

# Firebase cache
.firebase/

# Firebase config

# Uncomment this if you'd like others to create their own Firebase project.
# For a team working on the same Firebase project(s), it is recommended to leave
# it commented so all members can deploy to the same project(s) in .firebaserc.
# .firebaserc

# Runtime data
pids
*.pid
*.seed
*.pid.lock

# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov

# Coverage directory used by tools like istanbul
coverage

# nyc test coverage
.nyc_output

# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt

# Bower dependency directory (https://bower.io/)
bower_components

# node-waf configuration
.lock-wscript

# Compiled binary addons (http://nodejs.org/api/addons.html)
build/Release

# Dependency directories
node_modules/

# Optional npm cache directory
.npm

# Optional eslint cache
.eslintcache

# Optional REPL history
.node_repl_history

# Output of 'npm pack'
*.tgz

# Yarn Integrity file
.yarn-integrity

# dotenv environment variables file
.env

# dataconnect generated files
.dataconnect

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
connectorId: "movies"
connectorId: "tests"
authMode: "PUBLIC"
generate:
javascriptSdk:
outputDir: "./gen/web"
package: "@movie-app-ssr/movies"
package: "@test-app/tests"
10 changes: 10 additions & 0 deletions packages/data-connect/test/dataconnect/connector/mutations.gql
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
mutation RemovePost($id: UUID!) @auth(level: PUBLIC) {
post_delete(id: $id)
}
mutation AddPost($id: UUID!, $description: String!, $testId: String!) @auth(level: PUBLIC) {
post_insert(data: {
id: $id,
description: $description,
testId: $testId
})
}
17 changes: 17 additions & 0 deletions packages/data-connect/test/dataconnect/connector/queries.gql
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
query ListPosts($testId: String!) @auth(level: PUBLIC) {
posts(where: {
testId: {
eq: $testId
}
}) {
id,
description,
}
}

query UnauthorizedQuery {
posts {
id,
description
}
}
7 changes: 4 additions & 3 deletions packages/data-connect/test/dataconnect/dataconnect.yaml
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
specVersion: "v1beta"
serviceId: "dataconnect"
serviceId: "fdc-service"
location: "us-west2"
schema:
source: "./schema"
datasource:
postgresql:
database: "dataconnect-test"
database: "tests"
cloudSql:
instanceId: "local"
instanceId: "prod"
# schemaValidation: "COMPATIBLE"
connectorDirs: ["./connector"]
7 changes: 2 additions & 5 deletions packages/data-connect/test/dataconnect/schema/schema.gql
Original file line number Diff line number Diff line change
@@ -14,10 +14,7 @@
# product: Product!
# quantity: Int!
# }
type Movie @table {
id: String!
name: String!
genre: String!
type Post @table {
description: String!
test: String
testId: String!
}
10 changes: 10 additions & 0 deletions packages/data-connect/test/firebase.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"emulators": {
"dataconnect": {
"dataDir": "dataconnect/.dataconnect/pgliteData"
}
},
"dataconnect": {
"source": "dataconnect"
}
}
91 changes: 48 additions & 43 deletions packages/data-connect/test/queries.test.ts
Original file line number Diff line number Diff line change
@@ -29,86 +29,86 @@ import {
queryRef,
QueryResult,
SerializedRef,
subscribe,
terminate,
SOURCE_CACHE,
SOURCE_SERVER
SOURCE_SERVER,
subscribe,
terminate
} from '../src';

import { setupQueries } from './emulatorSeeder';
import { getConnectionConfig, initDatabase, PROJECT_ID } from './util';

use(chaiAsPromised);

interface Task {
interface Post {
id: string;
content: string;
description: string;
}
interface TaskListResponse {
posts: Task[];
interface PostListResponse {
posts: Post[];
}

const SEEDED_DATA = [
{
id: crypto.randomUUID(),
content: 'task 1'
description: 'task 1'
},
{
id: crypto.randomUUID(),
content: 'task 2'
description: 'task 2'
}
];
const REAL_DATA = SEEDED_DATA.map(obj => ({
...obj,
id: obj.id.replace(/-/g, '')
}));
function seedDatabase(instance: DataConnect): Promise<void> {
// call mutation query that adds SEEDED_DATA to database
return new Promise((resolve, reject) => {
async function run(): Promise<void> {
let idx = 0;
while (idx < SEEDED_DATA.length) {
const data = SEEDED_DATA[idx];
const ref = mutationRef(instance, 'seedDatabase', data);
await executeMutation(ref);
idx++;
}
}
run().then(resolve, reject);
});
}

async function deleteDatabase(instance: DataConnect): Promise<void> {
for (let i = 0; i < SEEDED_DATA.length; i++) {
const data = SEEDED_DATA[i];
const ref = mutationRef(instance, 'removePost', { id: data.id });
const ref = mutationRef(instance, 'RemovePost', { id: data.id });
await executeMutation(ref);
}
}
async function seedDatabase(
instance: DataConnect,
testId: string
): Promise<void> {
for (let i = 0; i < SEEDED_DATA.length; i++) {
const data = { ...SEEDED_DATA[i], testId };
const ref = mutationRef(instance, 'AddPost', data);
await executeMutation(ref);
}
}

interface PostVariables {
testId: string;
}
describe('DataConnect Tests', async () => {
let dc: DataConnect;
const TEST_ID = crypto.randomUUID();
beforeEach(async () => {
dc = initDatabase();
await setupQueries('queries.schema.gql', [
{ type: 'query', name: 'post' },
{ type: 'mutation', name: 'mutations' }
]);
await seedDatabase(dc);
await seedDatabase(dc, TEST_ID);
});
afterEach(async () => {
await deleteDatabase(dc);
await terminate(dc);
});
function getPostsRef(): QueryRef<PostListResponse, PostVariables> {
return queryRef<PostListResponse, PostVariables>(dc, 'ListPosts', {
testId: TEST_ID
});
}
it('Can get all posts', async () => {
const taskListQuery = queryRef<TaskListResponse>(dc, 'listPosts');
const taskListQuery = getPostsRef();
const taskListRes = await executeQuery(taskListQuery);
expect(taskListRes.data).to.deep.eq({
posts: REAL_DATA
});
});
it(`instantly executes a query if one hasn't been subscribed to`, async () => {
const taskListQuery = queryRef<TaskListResponse>(dc, 'listPosts');
const promise = new Promise<QueryResult<TaskListResponse, undefined>>(
const taskListQuery = getPostsRef();
const promise = new Promise<QueryResult<PostListResponse, PostVariables>>(
(resolve, reject) => {
const unsubscribe = subscribe(taskListQuery, {
onNext: res => {
@@ -129,17 +129,17 @@ describe('DataConnect Tests', async () => {
expect(res.source).to.eq(SOURCE_SERVER);
});
it(`returns the result source as cache when data already exists`, async () => {
const taskListQuery = queryRef<TaskListResponse>(dc, 'listPosts');
const taskListQuery = getPostsRef();
const queryResult = await executeQuery(taskListQuery);
const result = await waitForFirstEvent(taskListQuery);
expect(result.data).to.eq(queryResult.data);
expect(result.source).to.eq(SOURCE_CACHE);
});
it(`returns the proper JSON when calling .toJSON()`, async () => {
const taskListQuery = queryRef<TaskListResponse>(dc, 'listPosts');
const taskListQuery = getPostsRef();
await executeQuery(taskListQuery);
const result = await waitForFirstEvent(taskListQuery);
const serializedRef: SerializedRef<TaskListResponse, undefined> = {
const serializedRef: SerializedRef<PostListResponse, PostVariables> = {
data: {
posts: REAL_DATA
},
@@ -150,12 +150,14 @@ describe('DataConnect Tests', async () => {
projectId: PROJECT_ID
},
name: taskListQuery.name,
variables: undefined
variables: { testId: TEST_ID }
},
source: SOURCE_CACHE
};
expect(result.toJSON()).to.deep.eq(serializedRef);
expect(result.source).to.deep.eq(SOURCE_CACHE);
const json = result.toJSON();
expect(json.data).to.deep.eq(serializedRef.data);
expect(json.refInfo).to.deep.eq(serializedRef.refInfo);
expect(json.source).to.deep.eq(serializedRef.source);
});
it(`throws an error when the user can't connect to the server`, async () => {
// You can't point an existing data connect instance to a new emulator port, so we have to create a new one
@@ -165,13 +167,16 @@ describe('DataConnect Tests', async () => {
service: 'wrong'
});
connectDataConnectEmulator(fakeInstance, 'localhost', 3512);
const taskListQuery = queryRef<TaskListResponse>(fakeInstance, 'listPosts');
const taskListQuery = queryRef<PostListResponse>(fakeInstance, 'ListPosts');
await expect(executeQuery(taskListQuery)).to.eventually.be.rejectedWith(
'ECONNREFUSED'
/EADDRNOTAVAIL|ECONNREFUSED|Failed to fetch/
);
});
it('throws an error with just the message when the server responds with an error', async () => {
const invalidTaskListQuery = queryRef<TaskListResponse>(dc, 'listPosts2');
const invalidTaskListQuery = queryRef<PostListResponse>(
dc,
'UnauthorizedQuery'
);
const message =
'unauthorized: you are not authorized to perform this operation';
await expect(
30 changes: 20 additions & 10 deletions packages/data-connect/test/unit/dataconnect.test.ts
Original file line number Diff line number Diff line change
@@ -18,9 +18,10 @@
import { deleteApp, initializeApp } from '@firebase/app';
import { expect } from 'chai';

import { ConnectorConfig, getDataConnect } from '../../src';
import { getDataConnect } from '../../src';

describe('Data Connect Test', () => {
beforeEach(() => {});
it('should throw an error if `projectId` is not provided', async () => {
const app = initializeApp({ projectId: undefined }, 'a');
expect(() =>
@@ -30,24 +31,33 @@ describe('Data Connect Test', () => {
);
await deleteApp(app);
});
it('should not throw an error if `projectId` is provided', () => {
it('should not throw an error if `projectId` is provided', async () => {
const projectId = 'p';
initializeApp({ projectId });
const customApp = initializeApp({ projectId }, 'customApp');
expect(() =>
getDataConnect({ connector: 'c', location: 'l', service: 's' })
).to.not.throw(
'Project ID must be provided. Did you pass in a proper projectId to initializeApp?'
);
const dc = getDataConnect({ connector: 'c', location: 'l', service: 's' });
const dc = getDataConnect(customApp, {
connector: 'c',
location: 'l',
service: 's'
});
expect(dc.app.options.projectId).to.eq(projectId);
await deleteApp(customApp);
});
it('should throw an error if `connectorConfig` is not provided', () => {
it('should throw an error if `connectorConfig` is not provided', async () => {
const projectId = 'p';
initializeApp({ projectId });
expect(() => getDataConnect({} as ConnectorConfig)).to.throw(
'DC Option Required'
);
const dc = getDataConnect({ connector: 'c', location: 'l', service: 's' });
const customApp = initializeApp({ projectId }, 'customApp');
// @ts-ignore
expect(() => getDataConnect(customApp)).to.throw('DC Option Required');
const dc = getDataConnect(customApp, {
connector: 'c',
location: 'l',
service: 's'
});
expect(dc.app.options.projectId).to.eq(projectId);
await deleteApp(customApp);
});
});
3 changes: 2 additions & 1 deletion packages/data-connect/test/unit/transportoptions.test.ts
Original file line number Diff line number Diff line change
@@ -16,14 +16,15 @@
*/

import { expect } from 'chai';

import { queryRef } from '../../src';
import {
TransportOptions,
areTransportOptionsEqual,
connectDataConnectEmulator,
getDataConnect
} from '../../src/api/DataConnect';
import { app } from '../util';
import { queryRef } from '../../src';
describe('Transport Options', () => {
it('should return false if transport options are not equal', () => {
const transportOptions1: TransportOptions = {
7 changes: 4 additions & 3 deletions packages/data-connect/test/unit/utils.test.ts
Original file line number Diff line number Diff line change
@@ -19,6 +19,7 @@ import { expect } from 'chai';

import { getDataConnect } from '../../src';
import { validateArgs } from '../../src/util/validateArgs';
import { app } from '../util';
describe('Utils', () => {
it('[Vars required: true] should throw if no arguments are provided', () => {
const connectorConfig = { connector: 'c', location: 'l', service: 's' };
@@ -28,20 +29,20 @@ describe('Utils', () => {
});
it('[vars required: false, vars provided: false] should return data connect instance and no variables', () => {
const connectorConfig = { connector: 'c', location: 'l', service: 's' };
const dc = getDataConnect(connectorConfig);
const dc = getDataConnect(app, connectorConfig);
expect(validateArgs(connectorConfig)).to.deep.eq({ dc, vars: undefined });
});
it('[vars required: false, vars provided: false, data connect provided: true] should return data connect instance and no variables', () => {
const connectorConfig = { connector: 'c', location: 'l', service: 's' };
const dc = getDataConnect(connectorConfig);
const dc = getDataConnect(app, connectorConfig);
expect(validateArgs(connectorConfig, dc)).to.deep.eq({
dc,
vars: undefined
});
});
it('[vars required: true, vars provided: true, data connect provided: true] should return data connect instance and variables', () => {
const connectorConfig = { connector: 'c', location: 'l', service: 's' };
const dc = getDataConnect(connectorConfig);
const dc = getDataConnect(app, connectorConfig);
const vars = { a: 1 };
expect(validateArgs(connectorConfig, dc, vars)).to.deep.eq({ dc, vars });
});
13 changes: 6 additions & 7 deletions packages/data-connect/test/util.ts
Original file line number Diff line number Diff line change
@@ -24,13 +24,12 @@ import {
getDataConnect
} from '../src';

export const USE_EMULATOR = true;
export const EMULATOR_PORT = process.env.DC_EMULATOR_PORT;
// export const EMULATOR_PROJECT = process.env.PROJECT;
export const CONNECTOR_NAME = 'c';
export const LOCATION_NAME = 'l';
export const SERVICE_NAME = 'l';
export const PROJECT_ID = 'p';
const USE_EMULATOR = !!EMULATOR_PORT;
export const CONNECTOR_NAME = 'tests';
export const LOCATION_NAME = 'us-west2';
export const SERVICE_NAME = 'fdc-service';
export const PROJECT_ID = USE_EMULATOR ? 'p' : 'jscore-sandbox-141b5';
export function getConnectionConfig(): ConnectorConfig {
return {
connector: CONNECTOR_NAME,
@@ -46,7 +45,7 @@ export const app = initializeApp({
// Seed the database to have the proper fields to query, such as a list of tasks.
export function initDatabase(): DataConnect {
const instance = getDataConnect(getConnectionConfig());
if (!instance.isEmulator) {
if (USE_EMULATOR) {
connectDataConnectEmulator(instance, 'localhost', Number(EMULATOR_PORT));
}
return instance;
26 changes: 15 additions & 11 deletions scripts/emulator-testing/emulators/dataconnect-emulator.ts
Original file line number Diff line number Diff line change
@@ -18,34 +18,29 @@
import { platform } from 'os';
import { Emulator } from './emulator';

const DATABASE_EMULATOR_VERSION = '1.3.7';
const DATACONNECT_EMULATOR_VERSION = '1.7.5';

export class DataConnectEmulator extends Emulator {
// namespace: string;

constructor(port = 3628) {
constructor(port = 9399) {
const os = platform();
let urlString = '';
switch (os) {
case 'darwin':
urlString =
'https://firebasestorage.googleapis.com/v0/b/firemat-preview-drop/o/emulator%2Fdataconnect-emulator-macos-v1.3.7?alt=media&token=2cf32435-d479-4929-b963-a97ae1ac3f0b';
urlString = `https://firebasestorage.googleapis.com/v0/b/firemat-preview-drop/o/emulator%2Fdataconnect-emulator-macos-v${DATACONNECT_EMULATOR_VERSION}?alt=media`;
break;
case 'linux':
urlString =
'https://firebasestorage.googleapis.com/v0/b/firemat-preview-drop/o/emulator%2Fdataconnect-emulator-linux-v1.3.7?alt=media&token=fd33b4fc-2e27-4874-893a-2d1f0ecbf116';
urlString = `https://firebasestorage.googleapis.com/v0/b/firemat-preview-drop/o/emulator%2Fdataconnect-emulator-linux-v${DATACONNECT_EMULATOR_VERSION}?alt=media`;
break;
case 'win32':
urlString =
'https://firebasestorage.googleapis.com/v0/b/firemat-preview-drop/o/emulator%2Fdataconnect-emulator-windows-v1.3.7?alt=media&token=bd6e60b0-50b4-46db-aa6c-5fcc6e991f39';
urlString = `https://firebasestorage.googleapis.com/v0/b/firemat-preview-drop/o/emulator%2Fdataconnect-emulator-windows-v${DATACONNECT_EMULATOR_VERSION}?alt=media`;
break;
default:
throw new Error(
`We are unable to support your environment ${os} at this time.`
);
}
super(
`cli-v${DATABASE_EMULATOR_VERSION}`,
`cli-v${DATACONNECT_EMULATOR_VERSION}`,
// Use locked version of emulator for test to be deterministic.
// The latest version can be found from database emulator doc:
// https://firebase.google.com/docs/database/security/test-rules-emulator
@@ -54,4 +49,13 @@ export class DataConnectEmulator extends Emulator {
);
this.isDataConnect = true;
}
async setUp(): Promise<void> {
await super.setUp();
await fetch(`http://localhost:${this.port}/emulator/configure`, {
method: 'POST',
body: JSON.stringify({
'use_dummy': true
})
});
}
}
24 changes: 22 additions & 2 deletions scripts/emulator-testing/emulators/emulator.ts
Original file line number Diff line number Diff line change
@@ -123,18 +123,38 @@ export abstract class Emulator {
});
}

findDataConnectConfigDir() {
let path = './';
const files = fs.readdirSync(path);
if (files.includes('dataconnect')) {
return path + 'dataconnect';
}
if (files.includes('test')) {
return path + 'test/dataconnect';
}
throw new Error(
'Max Depth Exceeded. Please run from the data-connect/test folder'
);
}

setUp(): Promise<void> {
return new Promise<void>((resolve, reject) => {
if (!this.binaryPath) {
throw new Error('You must call download() before setUp()');
}
let promise: ChildProcessPromise<SpawnPromiseResult>;
if (this.isDataConnect) {
const dataConnectConfigDir = this.findDataConnectConfigDir();
promise = spawn(this.binaryPath, [
'--v=2',
'dev',
'--local_connection_string',
"'postgresql://postgres:secretpassword@localhost:5432/postgres?sslmode=disable'"
`--listen=127.0.0.1:${this.port},[::1]:${this.port}`,
`--config_dir=${dataConnectConfigDir}`
]);
promise.childProcess.stdout?.on('data', console.log);
promise.childProcess.stderr?.on('data', res =>
console.log(res.toString())
);
} else {
promise = spawn(
'java',