Skip to content

Commit

Permalink
Validation and Syntax Fixes
Browse files Browse the repository at this point in the history
Fixes to the validation tester
  • Loading branch information
arinaazmi authored and trollboss2572 committed Nov 29, 2024
1 parent 176bb37 commit a94bb8f
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 168 deletions.
25 changes: 2 additions & 23 deletions libs/checkpoint-firebase/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -228,21 +228,6 @@ export class FirebaseSaver extends BaseCheckpointSaver {
"Failed to serialized checkpoint and metadata to the same type."
);
}

/* We want to store the following (taken from MongoDB implementation)
- checkpoint ID
- checkpoint type
- checkpoint (serialized)
- metadata (serialized)*/

/* SQLite implementation also stores the following
- parent checkpoint ID
- thread ID,
- checkpoint_ns, */

/* I believe the excess values are stored for debugging purposes (hunch)
I am going to store the excess values as well here */

const data = {
thread_id: thread_id,
checkpoint_ns: checkpoint_ns,
Expand All @@ -253,15 +238,11 @@ export class FirebaseSaver extends BaseCheckpointSaver {
metadata: serializedMetadata
};

/* "thread_id", "checkpoint_ns", and "checkpoint_id"
form the "primary key" for this database */
const docKey = `${thread_id}_${checkpoint_ns}_${checkpoint.id}`;

/* Get a reference to the location in the database
where you want to store the data */

const dataRef = ref(this.db, `${this.checkpointCollectionName}/${docKey}`);

/* Use set to write the data to this reference */
await set(dataRef, data);

return {
Expand All @@ -273,7 +254,6 @@ export class FirebaseSaver extends BaseCheckpointSaver {
};
}

/* Saves intermediate writes associated with a checkpoint to the Firestore database. */
async putWrites(
config: RunnableConfig,
writes: PendingWrite[],
Expand Down Expand Up @@ -302,8 +282,7 @@ export class FirebaseSaver extends BaseCheckpointSaver {
const [channel, value] = write;
const [type, serializedValue] = this.serde.dumpsTyped(value);

/* "thread_id", "checkpoint_ns", "checkpoint_id", "taskId" and "idx"
form the "primary key" for each checkpoint write */

const writeKey = `${thread_id}_${checkpoint_ns}_${checkpoint_id}_${taskId}_${idx}`;

currentData[writeKey] = {
Expand Down
93 changes: 6 additions & 87 deletions libs/checkpoint-firebase/src/tests/checkpoints.int.test.ts
Original file line number Diff line number Diff line change
@@ -1,86 +1,8 @@
import { describe, it, expect, beforeAll, afterAll } from "@jest/globals";
import { describe, it, expect, afterAll } from "@jest/globals";
import { Checkpoint, CheckpointTuple, uuid6 } from "@langchain/langgraph-checkpoint";
import { FirebaseSaver } from "../index.js";
import { initializeApp } from "firebase/app";
import { getDatabase, ref, remove, Database } from "firebase/database";
import { GenericContainer, StartedTestContainer } from "testcontainers";

const FIREBASE_PORT = 9000;

// Example: Replace this URL with your database URL
const databaseURL = "https://your-database-name.firebaseio.com";

// Initialize Firebase App with only the databaseURL
const app = initializeApp({
databaseURL: databaseURL,
});

// Get the database instance
const database = getDatabase(app);

console.log("Database initialized with URL:", databaseURL);

// class FirebaseTestContainer {
// container?: StartedTestContainer;

// async start() {
// this.container = await new GenericContainer("firebase/firebase-tools")
// .withExposedPorts(FIREBASE_PORT)
// .withCmd([
// "emulators:start",
// "--only",
// "database",
// "--project",
// "test-project",
// ])
// .start();

// return this.getDatabaseUrl();
// }

// async stop() {
// if (this.container) {
// await this.container.stop();
// }
// }

// getDatabaseUrl() {
// if (!this.container) {
// throw new Error("Firebase container has not been started.");
// }

// const port = this.container.getMappedPort(FIREBASE_PORT);
// return `http://localhost:${port}`;
// }
// }

// const testContainer = new FirebaseTestContainer();

// export const initializer: any = {
// checkpointerName: "@langchain/langgraph-checkpoint-firebase",

// async beforeAll() {
// const databaseUrl = await testContainer.start();

// // Initialize Firebase Client SDK pointing to the emulator
// initializeApp({
// databaseURL: databaseUrl,
// });

// console.log(`Firebase Emulator running at ${databaseUrl}`);
// },

// beforeAllTimeout: 300_000, // five minutes to set up Firebase emulator

// async createCheckpointer() {
// const database = getDatabase();
// return new FirebaseSaver(database);
// },

// async afterAll() {
// await testContainer.stop();
// },
// };

// Define test checkpoints
const checkpoint1: Checkpoint = {
Expand Down Expand Up @@ -109,19 +31,16 @@ async function clearCollection(database: Database, path: string): Promise<void>
await remove(collectionRef);
}

let saver: FirebaseSaver;
let database: Database;
const app = initializeApp({
databaseURL: process.env.FIREBASE_URL
});

beforeAll(async () => {
await initializer.beforeAll();
saver = await initializer.createCheckpointer();
database = getDatabase(); // Access database for cleanup
}, initializer.beforeAllTimeout);
const database = getDatabase(app);
let saver = new FirebaseSaver(database);

afterAll(async () => {
await clearCollection(database, "checkpoints");
await clearCollection(database, "checkpoint-writes");
await initializer.afterAll();
});

describe("FirebaseSaver", () => {
Expand Down
2 changes: 1 addition & 1 deletion libs/checkpoint-validation/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@
"prettier": "^2.8.3",
"release-it": "^17.6.0",
"rollup": "^4.22.4",
"typescript": "^4.9.5 || ^5.4.5"
"typescript": "^5.7.2"
},
"publishConfig": {
"access": "public",
Expand Down
77 changes: 20 additions & 57 deletions libs/checkpoint-validation/src/tests/firebase_initializer.ts
Original file line number Diff line number Diff line change
@@ -1,78 +1,41 @@
import { FirebaseSaver } from "@langchain/langgraph-checkpoint-firebase";
import { initializeApp} from "firebase/app";
import { initializeApp } from "firebase/app";
import { getDatabase, Database } from "firebase/database";
import type { CheckpointerTestInitializer } from "../types.js";

import { GenericContainer, StartedTestContainer } from "testcontainers";
import { getDatabase} from "firebase/database";

const FIREBASE_PORT = 9000;

class FirebaseTestContainer {
container?: StartedTestContainer;

async start() {
this.container = await new GenericContainer("firebase/firebase-tools")
.withExposedPorts(FIREBASE_PORT)
.withCmd([
"emulators:start",
"--only",
"database",
"--project",
"test-project",
])
.start();

return this.getDatabaseUrl();
}

async stop() {
if (this.container) {
await this.container.stop();
}
}

getDatabaseUrl() {
if (!this.container) {
throw new Error("Firebase container has not been started.");
}

const port = this.container.getMappedPort(FIREBASE_PORT);
return `http://localhost:${port}`;
}
}



const testContainer = new FirebaseTestContainer();
let database: Database;

export const initializer: CheckpointerTestInitializer<FirebaseSaver> = {
checkpointerName: "@langchain/langgraph-checkpoint-firebase",

async beforeAll() {
const databaseUrl = await testContainer.start();
databaseUrl.getMappedPort()


// Initialize Firebase SDK pointing to the emulator
initializeApp({
apiKey: "fake-api-key", // Firebase requires a fake API key for emulator use
// Ensure the Firebase Emulator is running locally
const firebaseConfig = {
apiKey: "test-api-key",
authDomain: "localhost",
projectId: "test-project", // Match the emulator's projectId
databaseURL: ,
});
projectId: "test-project",
databaseURL: process.env.FIREBASEURL || "http://localhost:9000", // Use emulator URL
};
process.env.FIREBASE_URL = process.env.FIREBASEURL || "http://localhost:9000"
// Initialize Firebase app
const app = initializeApp(firebaseConfig);

// Initialize Firebase Realtime Database
database = getDatabase(app);

console.log(`Firebase Emulator running at ${databaseUrl}`);
console.log("Connected to Firebase Realtime Database Emulator");
},

beforeAllTimeout: 300_000, // five minutes to set up Firebase emulator
beforeAllTimeout: 300_000, // Allow up to 5 minutes for emulator setup

async createCheckpointer() {
const database = getDatabase();
// Create a new instance of FirebaseSaver with the initialized database
return new FirebaseSaver(database);
},

async afterAll() {
await testContainer.stop();
console.log("Cleaning up Firebase Realtime Database Emulator");
// Optionally, you can implement cleanup logic here if necessary
},
};

Expand Down

0 comments on commit a94bb8f

Please sign in to comment.