fix ts tests on windows (#1342)

* fix ts tests on windows

* fix cleanup

* fix tests

* hold on c sharp workflows

* fix: downloadModel doesnt not mkdirp
This commit is contained in:
Jacob Nguyen 2023-08-17 09:32:08 -05:00 committed by GitHub
parent a63093554f
commit b43eec0e2c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 34 additions and 11 deletions

View File

@ -931,18 +931,21 @@ workflows:
branches: branches:
only: only:
requires: requires:
- nuget-hold
- build-bindings-backend-linux - build-bindings-backend-linux
- build-csharp-windows: - build-csharp-windows:
filters: filters:
branches: branches:
only: only:
requires: requires:
- build-bindings-backend-windows - nuget-hold
- build-bindings-backend-windows
- build-csharp-macos: - build-csharp-macos:
filters: filters:
branches: branches:
only: only:
requires: requires:
- nuget-hold
- build-bindings-backend-macos - build-bindings-backend-macos
- store-and-upload-nupkgs: - store-and-upload-nupkgs:
filters: filters:

View File

@ -105,7 +105,7 @@ function downloadModel(modelName, options = {}) {
verbose: false, verbose: false,
...options, ...options,
}; };
const modelFileName = appendBinSuffixIfMissing(modelName); const modelFileName = appendBinSuffixIfMissing(modelName);
const partialModelPath = path.join( const partialModelPath = path.join(
downloadOptions.modelPath, downloadOptions.modelPath,
@ -115,6 +115,8 @@ function downloadModel(modelName, options = {}) {
const modelUrl = const modelUrl =
downloadOptions.url ?? `https://gpt4all.io/models/${modelFileName}`; downloadOptions.url ?? `https://gpt4all.io/models/${modelFileName}`;
mkdirp.sync(downloadOptions.modelPath)
if (existsSync(finalModelPath)) { if (existsSync(finalModelPath)) {
throw Error(`Model already exists at ${finalModelPath}`); throw Error(`Model already exists at ${finalModelPath}`);
} }

View File

@ -1,6 +1,7 @@
const path = require("node:path"); const path = require("node:path");
const os = require("node:os"); const os = require("node:os");
const fsp = require("node:fs/promises"); const fsp = require("node:fs/promises");
const { existsSync } = require('node:fs');
const { LLModel } = require("node-gyp-build")(path.resolve(__dirname, "..")); const { LLModel } = require("node-gyp-build")(path.resolve(__dirname, ".."));
const { const {
listModels, listModels,
@ -19,6 +20,7 @@ const {
createCompletion, createCompletion,
} = require("../src/gpt4all.js"); } = require("../src/gpt4all.js");
const { mock } = require("node:test"); const { mock } = require("node:test");
const { mkdirp } = require("mkdirp");
describe("config", () => { describe("config", () => {
test("default paths constants are available and correct", () => { test("default paths constants are available and correct", () => {
@ -116,7 +118,7 @@ describe("downloadModel", () => {
return mockFetchImplementation; return mockFetchImplementation;
}; };
beforeEach(() => { beforeEach(async () => {
// Mocking the AbortController constructor // Mocking the AbortController constructor
mockAbortController = jest.fn(); mockAbortController = jest.fn();
global.AbortController = mockAbortController; global.AbortController = mockAbortController;
@ -126,19 +128,35 @@ describe("downloadModel", () => {
}); });
mockFetch = createMockFetch(); mockFetch = createMockFetch();
jest.spyOn(global, "fetch").mockImplementation(mockFetch); jest.spyOn(global, "fetch").mockImplementation(mockFetch);
}); });
afterEach(() => { afterEach(async () => {
// Clean up mocks // Clean up mocks
mockAbortController.mockReset(); mockAbortController.mockReset();
mockFetch.mockClear(); mockFetch.mockClear();
global.fetch.mockRestore(); global.fetch.mockRestore();
const rootDefaultPath = path.resolve(DEFAULT_DIRECTORY),
partialPath = path.resolve(rootDefaultPath, fakeModelName+'.part'),
fullPath = path.resolve(rootDefaultPath, fakeModelName+'.bin')
//if tests fail, remove the created files
// acts as cleanup if tests fail
//
if(existsSync(fullPath)) {
await fsp.rm(fullPath)
}
if(existsSync(partialPath)) {
await fsp.rm(partialPath)
}
}); });
test("should successfully download a model file", async () => { test("should successfully download a model file", async () => {
const downloadController = downloadModel(fakeModelName); const downloadController = downloadModel(fakeModelName);
const modelFilePath = await downloadController.promise; const modelFilePath = await downloadController.promise;
expect(modelFilePath).toBe(`${DEFAULT_DIRECTORY}/${fakeModelName}.bin`); expect(modelFilePath).toBe(path.resolve(DEFAULT_DIRECTORY, `${fakeModelName}.bin`));
expect(global.fetch).toHaveBeenCalledTimes(1); expect(global.fetch).toHaveBeenCalledTimes(1);
expect(global.fetch).toHaveBeenCalledWith( expect(global.fetch).toHaveBeenCalledWith(
@ -153,7 +171,7 @@ describe("downloadModel", () => {
); );
// final model file should be present // final model file should be present
expect(fsp.access(modelFilePath)).resolves.not.toThrow(); await expect(fsp.access(modelFilePath)).resolves.not.toThrow();
// remove the testing model file // remove the testing model file
await fsp.unlink(modelFilePath); await fsp.unlink(modelFilePath);
@ -165,17 +183,17 @@ describe("downloadModel", () => {
}); });
// the promise should reject with a mismatch // the promise should reject with a mismatch
await expect(downloadController.promise).rejects.toThrow( await expect(downloadController.promise).rejects.toThrow(
`Model "${fakeModelName}" failed verification: Hashes mismatch.` `Model "fake-model" failed verification: Hashes mismatch. Expected wrong-md5sum, got 08d6c05a21512a79a1dfeb9d2a8f262f`
); );
// fetch should have been called // fetch should have been called
expect(global.fetch).toHaveBeenCalledTimes(1); expect(global.fetch).toHaveBeenCalledTimes(1);
// the file should be missing // the file should be missing
expect( await expect(
fsp.access(`${DEFAULT_DIRECTORY}/${fakeModelName}.bin`) fsp.access(path.resolve(DEFAULT_DIRECTORY, `${fakeModelName}.bin`))
).rejects.toThrow(); ).rejects.toThrow();
// partial file should also be missing // partial file should also be missing
expect( await expect(
fsp.access(`${DEFAULT_DIRECTORY}/${fakeModelName}.part`) fsp.access(path.resolve(DEFAULT_DIRECTORY, `${fakeModelName}.part`))
).rejects.toThrow(); ).rejects.toThrow();
}); });