From 36b7236c8a1d664d451bf2b333e0866b3ddd64d1 Mon Sep 17 00:00:00 2001 From: KATTA-00 Date: Thu, 8 Aug 2024 16:48:56 +0530 Subject: [PATCH 01/36] adding test and mock server implementations --- ballerina/Dependencies.toml | 34 ++- ballerina/client.bal | 2 +- ballerina/sample.jsonl | 4 + ballerina/tests/openapi_service.bal | 391 ++++++++++++++++++++++++++ ballerina/tests/test.bal | 422 ++++++++++++++++++++++++++++ ballerina/types.bal | 12 + 6 files changed, 863 insertions(+), 2 deletions(-) create mode 100644 ballerina/sample.jsonl create mode 100644 ballerina/tests/openapi_service.bal create mode 100644 ballerina/tests/test.bal diff --git a/ballerina/Dependencies.toml b/ballerina/Dependencies.toml index c58708a..3877ff3 100644 --- a/ballerina/Dependencies.toml +++ b/ballerina/Dependencies.toml @@ -93,11 +93,14 @@ modules = [ [[package]] org = "ballerina" name = "io" -version = "1.6.0" +version = "1.6.1" dependencies = [ {org = "ballerina", name = "jballerina.java"}, {org = "ballerina", name = "lang.value"} ] +modules = [ + {org = "ballerina", packageName = "io", moduleName = "io"} +] [[package]] org = "ballerina" @@ -144,6 +147,15 @@ dependencies = [ {org = "ballerina", name = "jballerina.java"} ] +[[package]] +org = "ballerina" +name = "lang.error" +version = "0.0.0" +scope = "testOnly" +dependencies = [ + {org = "ballerina", name = "jballerina.java"} +] + [[package]] org = "ballerina" name = "lang.int" @@ -202,6 +214,9 @@ dependencies = [ {org = "ballerina", name = "lang.value"}, {org = "ballerina", name = "observe"} ] +modules = [ + {org = "ballerina", packageName = "log", moduleName = "log"} +] [[package]] org = "ballerina" @@ -255,6 +270,20 @@ dependencies = [ {org = "ballerina", name = "time"} ] +[[package]] +org = "ballerina" +name = "test" +version = "0.0.0" +scope = "testOnly" +dependencies = [ + {org = "ballerina", name = "jballerina.java"}, + {org = "ballerina", name = "lang.array"}, + {org = "ballerina", name = "lang.error"} +] +modules = [ + {org = "ballerina", packageName = "test", moduleName = "test"} +] + [[package]] org = "ballerina" name = "time" @@ -292,7 +321,10 @@ name = "openai.finetunes" version = "1.0.5" dependencies = [ {org = "ballerina", name = "http"}, + {org = "ballerina", name = "io"}, + {org = "ballerina", name = "log"}, {org = "ballerina", name = "mime"}, + {org = "ballerina", name = "test"}, {org = "ballerina", name = "url"}, {org = "ballerinai", name = "observe"} ] diff --git a/ballerina/client.bal b/ballerina/client.bal index e42dbd6..72c21eb 100644 --- a/ballerina/client.bal +++ b/ballerina/client.bal @@ -102,7 +102,7 @@ public isolated client class Client { # + file_id - The ID of the file to use for this request. # + headers - Headers to be sent with the request # + return - OK - resource isolated function get files/[string file_id]/content(map headers = {}) returns string|error { + resource isolated function get files/[string file_id]/content(map headers = {}) returns byte[]|error { string resourcePath = string `/files/${getEncodedUri(file_id)}/content`; return self.clientEp->get(resourcePath, headers); } diff --git a/ballerina/sample.jsonl b/ballerina/sample.jsonl new file mode 100644 index 0000000..aadb8b9 --- /dev/null +++ b/ballerina/sample.jsonl @@ -0,0 +1,4 @@ +{ + "prompt": "What is the answer to 2+2", + "completion": "4" +} \ No newline at end of file diff --git a/ballerina/tests/openapi_service.bal b/ballerina/tests/openapi_service.bal new file mode 100644 index 0000000..c87e6c4 --- /dev/null +++ b/ballerina/tests/openapi_service.bal @@ -0,0 +1,391 @@ +// AUTO-GENERATED FILE. DO NOT MODIFY. +// This file is auto-generated by the Ballerina OpenAPI tool. + +// Copyright (c) 2024, WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you under the Apache License, +// Version 2.0 (the "License"); you may not use this file except +// in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +import ballerina/http; +import ballerina/log; + +listener http:Listener httpListener = new (9090); + +http:Service mockService = service object { + + // # Delete a file. + // # + // # + file_id - The ID of the file to use for this request. + // # + return - OK + // resource function delete files/[string file_id]() returns DeleteFileResponse { + // } + + // # Delete a fine-tuned model. You must have the Owner role in your organization to delete a model. + // # + // # + model - The model to delete + // # + return - OK + // resource function delete models/[string model]() returns DeleteModelResponse { + // } + + # Returns a list of files that belong to the user's organization. + # + # + purpose - Only return files with the given purpose. + # + return - OK + resource function get files(string? purpose) returns ListFilesResponse { + + ListFilesResponse response = { + 'object: "list", + data: [ + { + 'object: "file", + id: "file-JZMH9Xxnt7Hg2io6N2kzmlzM", + purpose: "fine-tune", + filename: "sample.jsonl", + bytes: 71, + created_at: 1723097702, + status: "processed", + status_details: null + }, + { + 'object: "file", + id: "file-JZMH9Xxnt7Hg2io6N2kzmlzM", + purpose: "fine-tune", + filename: "sample.jsonl", + bytes: 71, + created_at: 1723097702, + status: "processed", + status_details: null + } + ] + }; + + return response; + + } + + # Returns information about a specific file. + # + # + file_id - The ID of the file to use for this request. + # + return - OK + resource function get files/[string file_id]() returns OpenAIFile { + + OpenAIFile response = { + 'object: "file", + id: file_id, + purpose: "fine-tune", + filename: "sample.jsonl", + bytes: 71, + created_at: 1723097702, + status: "processed", + status_details: null + }; + + return response; + + } + + # Returns the contents of the specified file. + # + # + file_id - The ID of the file to use for this request. + # + return - OK + resource function get files/[string file_id]/content() returns byte[] { + + byte[] response = [123, 34, 116, 101, 120, 116, 34, 58, 34, 72, 101, 108, 108, 111, 44, 32, 87, 111, 114, 108, 100, 34, 125]; + + return response; + + } + + # List your organization's fine-tuning jobs + # + # + after - Identifier for the last job from the previous pagination request. + # + 'limit - Number of fine-tuning jobs to retrieve. + # + return - OK + resource function get fine_tuning/jobs(string? after, int 'limit = 20) returns ListPaginatedFineTuningJobsResponse { + + ListPaginatedFineTuningJobsResponse response = { + "object": "list", + "data": [ + { + "object": "fine_tuning.job", + "id": "ftjob-G0rwrYUnRwEWPjDRvxByxPxU", + "model": "gpt-3.5-turbo-0125", + "created_at": 1723097706, + "finished_at": null, + "fine_tuned_model": null, + "organization_id": "org-Gzp0rlPk9gw4JaNXmPqDJ1H4", + "result_files": [], + "status": "failed", + "validation_file": null, + "training_file": "file-JZMH9Xxnt7Hg2io6N2kzmlzM", + "hyperparameters": { + "n_epochs": "auto", + "batch_size": "auto", + "learning_rate_multiplier": "auto" + }, + "trained_tokens": null, + "error": { + "code": "invalid_training_file", + "param": "training_file", + "message": "The job failed due to an invalid training file. Expected file to have JSONL format, where every line is a valid JSON dictionary. Line 1 is not a dictionary." + }, + "user_provided_suffix": null, + "seed": 1913581589, + "estimated_finish": null, + "integrations": [] + } + ], + "has_more": false + }; + + return response; + + } + + # Get info about a fine-tuning job. + # + # [Learn more about fine-tuning](/docs/guides/fine-tuning) + # + # + fine_tuning_job_id - The ID of the fine-tuning job. + # + return - OK + resource function get fine_tuning/jobs/[string fine_tuning_job_id]() returns FineTuningJob { + + FineTuningJob response = { + "object": "fine_tuning.job", + "id": fine_tuning_job_id, + "model": "gpt-3.5-turbo-0125", + "created_at": 1723097706, + "finished_at": null, + "fine_tuned_model": null, + "organization_id": "org-Gzp0rlPk9gw4JaNXmPqDJ1H4", + "result_files": [], + "status": "failed", + "validation_file": null, + "training_file": "file-JZMH9Xxnt7Hg2io6N2kzmlzM", + "hyperparameters": { + "n_epochs": "auto", + "batch_size": "auto", + "learning_rate_multiplier": "auto" + }, + "trained_tokens": null, + "error": { + "code": "invalid_training_file", + "param": "training_file", + "message": "The job failed due to an invalid training file. Expected file to have JSONL format, where every line is a valid JSON dictionary. Line 1 is not a dictionary." + }, + "user_provided_suffix": null, + "seed": 1913581589, + "estimated_finish": null, + "integrations": [] + }; + + return response; + + } + + # List checkpoints for a fine-tuning job. + # + # + fine_tuning_job_id - The ID of the fine-tuning job to get checkpoints for. + # + after - Identifier for the last checkpoint ID from the previous pagination request. + # + 'limit - Number of checkpoints to retrieve. + # + return - OK + resource function get fine_tuning/jobs/[string fine_tuning_job_id]/checkpoints(string? after, int 'limit = 10) returns ListFineTuningJobCheckpointsResponse { + + ListFineTuningJobCheckpointsResponse response = { + "object": "list", + "data": [ + { + "id": "checkpoint-1", + "created_at": 1723110882, + "object": "fine_tuning.job.checkpoint", + "fine_tuned_model_checkpoint": "gpt-3.5-turbo-0125-1", + "fine_tuning_job_id": fine_tuning_job_id, + "metrics": { + "step":1 + }, + "step_number": 2 + } + ], + "has_more": false + }; + + return response; + + } + + # Get status updates for a fine-tuning job. + # + # + fine_tuning_job_id - The ID of the fine-tuning job to get events for. + # + after - Identifier for the last event from the previous pagination request. + # + 'limit - Number of events to retrieve. + # + return - OK + resource function get fine_tuning/jobs/[string fine_tuning_job_id]/events(string? after, int 'limit = 20) returns ListFineTuningJobEventsResponse { + + ListFineTuningJobEventsResponse response = { + "object": "list", + "data": [ + { + "id": fine_tuning_job_id, + "created_at": 1723110882, + "level": "warn", + "message": "Fine-tuning job started.", + "object": "fine_tuning.job.event" + } + ] + }; + + return response; + + } + + # Lists the currently available models, and provides basic information about each one such as the owner and availability. + # + # + return - OK + resource function get models() returns ListModelsResponse { + + ListModelsResponse response = { + 'object: "list", + data: [ + { + id: "dall-e-3", + 'object: "model", + created: 1698785189, + owned_by: "system" + }, + { + id: "dall-e-3", + 'object: "model", + created: 1698785189, + owned_by: "system" + } + ] + }; + + return response; + + } + + # Retrieves a model instance, providing basic information about the model such as the owner and permissioning. + # + # + model - The ID of the model to use for this request + # + return - OK + resource function get models/[string model]() returns Model { + + Model response = { + id: model, + 'object: "model", + created: 1698785189, + owned_by: "system" + }; + + return response; + + } + + # Upload a file that can be used across various endpoints. Individual files can be up to 512 MB, and the size of all files uploaded by one organization can be up to 100 GB. + # + # The Assistants API supports files up to 2 million tokens and of specific file types. See the [Assistants Tools guide](/docs/assistants/tools) for details. + # + # The Fine-tuning API only supports `.jsonl` files. The input also has certain required formats for fine-tuning [chat](/docs/api-reference/fine-tuning/chat-input) or [completions](/docs/api-reference/fine-tuning/completions-input) models. + # + # The Batch API only supports `.jsonl` files up to 100 MB in size. The input also has a specific required [format](/docs/api-reference/batch/request-input). + # + # Please [contact us](https://help.openai.com/) if you need to increase these storage limits. + # + # + return - OK + resource function post files(http:Request request) returns OkOpenAIFile { + + OkOpenAIFile response = { + body: { + 'object: "file", + id: "file-JZMH9Xxnt7Hg2io6N2kzmlzM", + purpose: "fine-tune", + filename: "sample.jsonl", + bytes: 71, + created_at: 1723097702, + status: "processed", + status_details: null + }, + headers: { + "Content-Type": "application/json" + } + }; + + return response; + + } + + # Creates a fine-tuning job which begins the process of creating a new model from a given dataset. + # + # Response includes details of the enqueued job including job status and the name of the fine-tuned models once complete. + # + # [Learn more about fine-tuning](/docs/guides/fine-tuning) + # + # + return - OK + resource function post fine_tuning/jobs(@http:Payload CreateFineTuningJobRequest payload) returns OkFineTuningJob { + + OkFineTuningJob response = { + body:{ + "object": "fine_tuning.job", + "id": "ftjob-5NikxOY1BsPHxt8Z8YBm8AX1", + "model": "gpt-3.5-turbo-0125", + "created_at": 1723110882, + "finished_at": null, + "fine_tuned_model": null, + "organization_id": "org-Gzp0rlPk9gw4JaNXmPqDJ1H4", + "result_files": [], + "status": "validating_files", + "validation_file": null, + "training_file": "file-JZMH9Xxnt7Hg2io6N2kzmlzM", + "hyperparameters": { + "n_epochs": "auto", + "batch_size": "auto", + "learning_rate_multiplier": "auto" + }, + "trained_tokens": null, + "error": {}, + "user_provided_suffix": null, + "seed": 1776549854, + "estimated_finish": null, + "integrations": [] + }, + headers: { + "Content-Type": "application/json" + } + }; + + return response; + + } + + // # Immediately cancel a fine-tune job. + // # + // # + fine_tuning_job_id - The ID of the fine-tuning job to cancel. + // # + return - OK + // resource function post fine_tuning/jobs/[string fine_tuning_job_id]/cancel() returns OkFineTuningJob { + // } +}; + + +function init() returns error? { + + if isLiveServer { + log:printInfo("Skiping mock server initialization as the tests are running on live server"); + return; + } + + log:printInfo("Initiating mock server"); + check httpListener.attach(mockService, "/"); + check httpListener.'start(); +} \ No newline at end of file diff --git a/ballerina/tests/test.bal b/ballerina/tests/test.bal new file mode 100644 index 0000000..81874c5 --- /dev/null +++ b/ballerina/tests/test.bal @@ -0,0 +1,422 @@ +// AUTO-GENERATED FILE. DO NOT MODIFY. +// This file is auto-generated by the Ballerina OpenAPI tool. + +// Copyright (c) 2024, WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you under the Apache License, +// Version 2.0 (the "License"); you may not use this file except +// in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +import ballerina/test; +import ballerina/io; + +configurable boolean isLiveServer = ?; +configurable string token = ?; +configurable string serviceUrl = isLiveServer ? "https://api.openai.com/v1" : "http://localhost:9090"; +final ConnectionConfig config = {auth: {token}}; + +final Client baseClient = check new Client(config, serviceUrl); +final string fileName = "sample.jsonl"; + +// Models + +@test:Config {} +isolated function testListModels() returns error? { + + ListModelsResponse|error modelsResponse = check baseClient->/models.get(); + + if (modelsResponse is ListModelsResponse) { + test:assertEquals(modelsResponse.'object, "list", "Object type mismatched"); + test:assertTrue(modelsResponse.hasKey("data"), "Response does not have the key 'data'"); + } else { + return modelsResponse; + } +} + +@test:Config { + dependsOn: [testListModels] +} +isolated function testRetrieveModel() returns error? { + + ListModelsResponse|error modelsResponse = check baseClient->/models.get(); + + string modelId = "gpt-3.5-turbo"; + + if (modelsResponse is ListModelsResponse) { + modelId = modelsResponse.data[0].id; + } else { + return modelsResponse; + } + + Model|error modelResponse = baseClient->/models/[modelId].get(); + + if (modelResponse is Model) { + test:assertEquals(modelResponse.id, modelId, "Model id mismatched"); + test:assertTrue(modelResponse.hasKey("object"), "Response does not have the key 'object'"); + } else { + return modelResponse; + } + +} + +// @test:Config { +// dependsOn: [testCreateFineTuningJob, testListModels] +// } +// isolated function testDeleteModel() returns error? { + +// byte[]|error fileContent = io:fileReadBytes(fileName); + +// if (fileContent is error) { +// return fileContent; +// } + +// CreateFileRequest fileRequest = { +// file: {fileContent, fileName}, +// purpose: "fine-tune" +// }; + +// OpenAIFile|error fileResponse = baseClient->/files.post(fileRequest); + +// if (fileResponse is error) { +// return fileResponse; +// } + +// string fileId = fileResponse.id; + +// ListModelsResponse|error modelsResponse = baseClient->/models.get(); + +// if (modelsResponse is error) { +// return modelsResponse; +// } + +// // string modelId = modelsResponse.data[0].id; +// string modelId = "gpt-3.5-turbo"; + +// CreateFineTuningJobRequest fineTuneRequest = { +// model: modelId, +// training_file: fileId +// }; + +// FineTuningJob|error fineTuneResponse = baseClient->/fine_tuning/jobs.post(fineTuneRequest); + +// if (fineTuneResponse is error) { +// return fineTuneResponse; +// } + +// string modelIdCreated = fineTuneResponse.model; + +// DeleteModelResponse|error modelResponseDelete = baseClient->/models/[modelIdCreated].delete(); + +// if (modelResponseDelete is DeleteModelResponse) { +// test:assertEquals(modelResponseDelete.id, modelIdCreated, "Model id mismatched"); +// test:assertTrue(modelResponseDelete.hasKey("object"), "Response does not have the key 'object'"); +// } else { +// return modelResponseDelete; +// } +// } + +// // Files + +@test:Config {} +isolated function testListFiles() returns error? { + + ListFilesResponse|error filesResponse = baseClient->/files.get(); + + if (filesResponse is ListFilesResponse) { + test:assertEquals(filesResponse.'object, "list", "Object type mismatched"); + test:assertTrue(filesResponse.hasKey("data"), "Response does not have the key 'data'"); + } else { + return filesResponse; + } + +} + +@test:Config { + dependsOn: [testListFiles] +} +isolated function testCreateFile() returns error? { + + byte[]|error fileContent = io:fileReadBytes(fileName); + + if (fileContent is error) { + return fileContent; + } + + CreateFileRequest fileRequest = { + file: {fileContent, fileName}, + purpose: "fine-tune" + }; + + OpenAIFile|error fileResponse = baseClient->/files.post(fileRequest); + + if (fileResponse is error) { + return fileResponse; + } + + test:assertEquals(fileResponse.purpose, "fine-tune", "Purpose mismatched"); + test:assertTrue(fileResponse.id !is "", "File id is empty"); +} + +@test:Config { + // dependsOn: [testCreateFile] +} +isolated function testRetrieveFile() returns error? { + + ListFilesResponse|error filesResponse = baseClient->/files.get(); + + if (filesResponse is ListFilesResponse) { + + string fileId = filesResponse.data[0].id; + + OpenAIFile|error fileResponse = baseClient->/files/[fileId].get(); + + if (fileResponse is OpenAIFile) { + test:assertEquals(fileResponse.id, fileId, "File id mismatched"); + test:assertTrue(fileResponse.hasKey("object"), "Response does not have the key 'object'"); + } else { + return fileResponse; + } + } else { + return filesResponse; + } +} + +@test:Config { + dependsOn: [testCreateFile, testRetrieveFile, testListFiles] +} +isolated function testDownloadFile() returns error? { + + byte[]|error fileContent = io:fileReadBytes(fileName); + + if (fileContent is error) { + return fileContent; + } + + CreateFileRequest fileRequest = { + file: {fileContent, fileName}, + purpose: "fine-tune" + }; + + OpenAIFile|error fileResponse = baseClient->/files.post(fileRequest); + + if (fileResponse is error) { + return fileResponse; + } + + string fileId = fileResponse.id; + + byte[]|error fileContentDownload = baseClient->/files/[fileId]/content.get(); + + if (fileContentDownload is error) { + return fileContentDownload; + } +} + +// @test:Config { +// dependsOn: [testCreateFile, testRetrieveFile, testListFiles] +// } +// isolated function testDeleteFile() returns error? { + +// byte[]|error fileContent = io:fileReadBytes(fileName); + +// if (fileContent is error) { +// return fileContent; +// } + +// CreateFileRequest fileRequest = { +// file: {fileContent, fileName}, +// purpose: "fine-tune" +// }; + +// OpenAIFile|error fileResponse = baseClient->/files.post(fileRequest); + +// if (fileResponse is error) { +// return fileResponse; +// } + +// string fileId = fileResponse.id; + +// DeleteFileResponse|error fileResponseDelete = baseClient->/files/[fileId].delete(); + +// if (fileResponseDelete is DeleteFileResponse) { +// test:assertEquals(fileResponseDelete.id, fileId, "File id mismatched"); +// test:assertTrue(fileResponseDelete.hasKey("object"), "Response does not have the key 'object'"); +// } else { +// return fileResponseDelete; +// } +// } + +// // Fine Tuning Jobs + +@test:Config {} +isolated function testListPaginatedFineTuningJobs() returns error? { + + ListPaginatedFineTuningJobsResponse|error jobsResponse = baseClient->/fine_tuning/jobs.get(); + + if (jobsResponse is ListPaginatedFineTuningJobsResponse) { + test:assertEquals(jobsResponse.'object, "list", "Object type mismatched"); + test:assertTrue(jobsResponse.hasKey("data"), "Response does not have the key 'data'"); + } else { + return jobsResponse; + } +} + +@test:Config { + dependsOn: [testListPaginatedFineTuningJobs, testListModels, testCreateFile, testRetrieveFile, testListFiles] +} +isolated function testCreateFineTuningJob() returns error? { + + byte[]|error fileContent = io:fileReadBytes(fileName); + + if (fileContent is error) { + return fileContent; + } + + CreateFileRequest fileRequest = { + file: {fileContent, fileName}, + purpose: "fine-tune" + }; + + OpenAIFile|error fileResponse = baseClient->/files.post(fileRequest); + + if (fileResponse is error) { + return fileResponse; + } + + string fileId = fileResponse.id; + + ListModelsResponse|error modelsResponse = baseClient->/models.get(); + + if (modelsResponse is error) { + return modelsResponse; + } + + // string modelId = modelsResponse.data[0].id; + string modelId = "gpt-3.5-turbo"; + + CreateFineTuningJobRequest fineTuneRequest = { + model: modelId, + training_file: fileId + }; + + FineTuningJob|error fineTuneResponse = baseClient->/fine_tuning/jobs.post(fineTuneRequest); + + if (fineTuneResponse is FineTuningJob) { + test:assertTrue(fineTuneResponse.hasKey("object"), "Response does not have the key 'object'"); + test:assertTrue(fineTuneResponse.hasKey("id"), "Response does not have the key 'id'"); + } else { + return fineTuneResponse; + } + +} + +@test:Config { + dependsOn: [testCreateFineTuningJob] +} +isolated function testRetrieveFineTuningJob() returns error? { + + ListPaginatedFineTuningJobsResponse|error jobsResponse = baseClient->/fine_tuning/jobs.get(); + + if (jobsResponse is ListPaginatedFineTuningJobsResponse) { + string jobId = jobsResponse.data[0].id; + + FineTuningJob|error jobResponse = baseClient->/fine_tuning/jobs/[jobId].get(); + + if (jobResponse is FineTuningJob) { + test:assertEquals(jobResponse.id, jobId, "Job id mismatched"); + test:assertTrue(jobResponse.hasKey("object"), "Response does not have the key 'object'"); + } else { + return jobResponse; + } + } else { + return jobsResponse; + } + +} + +@test:Config { + dependsOn: [testCreateFineTuningJob] +} +isolated function testListFineTuningEvents() returns error? { + + string fine_tuning_job_id = "ftjob-qxrbfm03AOBVju8HYytXc0lN"; + + ListPaginatedFineTuningJobsResponse|error jobsResponse = baseClient->/fine_tuning/jobs.get(); + + if (jobsResponse is ListPaginatedFineTuningJobsResponse) { + fine_tuning_job_id = jobsResponse.data[0].id; + } else { + return jobsResponse; + } + + ListFineTuningJobEventsResponse|error eventsResponse = baseClient->/fine_tuning/jobs/[fine_tuning_job_id]/events.get(); + + if (eventsResponse is ListFineTuningJobEventsResponse) { + test:assertEquals(eventsResponse.'object, "list", "Object type mismatched"); + test:assertTrue(eventsResponse.hasKey("data"), "Response does not have the key 'data'"); + } else { + return eventsResponse; + } + +} + +@test:Config { + dependsOn: [testCreateFineTuningJob] +} +isolated function testListFineTuningJobCheckpoints() returns error? { + + string fine_tuning_job_id = "ftjob-qxrbfm03AOBVju8HYytXc0lN"; + + ListPaginatedFineTuningJobsResponse|error jobsResponse = baseClient->/fine_tuning/jobs.get(); + + if (jobsResponse is ListPaginatedFineTuningJobsResponse) { + fine_tuning_job_id = jobsResponse.data[0].id; + } else { + return jobsResponse; + } + + ListFineTuningJobCheckpointsResponse|error checkpointsResponse = baseClient->/fine_tuning/jobs/[fine_tuning_job_id]/checkpoints.get(); + + if (checkpointsResponse is ListFineTuningJobCheckpointsResponse) { + test:assertEquals(checkpointsResponse.'object, "list", "Object type mismatched"); + test:assertTrue(checkpointsResponse.hasKey("data"), "Response does not have the key 'data'"); + } else { + return checkpointsResponse; + } + +} + +// @test:Config { +// dependsOn: [testCreateFineTuningJob] +// } +// isolated function testCancelFineTuningJob() returns error? { + +// string fine_tuning_job_id = "ftjob-qxrbfm03AOBVju8HYytXc0lN"; + +// ListPaginatedFineTuningJobsResponse|error jobsResponse = baseClient->/fine_tuning/jobs.get(); + +// if (jobsResponse is ListPaginatedFineTuningJobsResponse) { +// fine_tuning_job_id = jobsResponse.data[0].id; +// } else { +// return jobsResponse; +// } + +// FineTuningJob|error jobResponse = baseClient->/fine_tuning/jobs/[fine_tuning_job_id]/cancel.post(); + +// if (jobResponse is FineTuningJob) { +// test:assertEquals(jobResponse.id, fine_tuning_job_id, "Job id mismatched"); +// test:assertTrue(jobResponse.hasKey("object"), "Response does not have the key 'object'"); +// } else { +// return jobResponse; +// } +// } \ No newline at end of file diff --git a/ballerina/types.bal b/ballerina/types.bal index 093632d..9212cdf 100644 --- a/ballerina/types.bal +++ b/ballerina/types.bal @@ -168,6 +168,12 @@ public type ListFineTuningJobCheckpointsResponse record { boolean has_more; }; +public type OkFineTuningJob record {| + *http:Ok; + FineTuningJob body; + map headers; +|}; + public type DeleteModelResponse record { string id; boolean deleted; @@ -300,6 +306,12 @@ public type CreateFineTuningJobRequest_integrations record { CreateFineTuningJobRequest_wandb wandb; }; +public type OkOpenAIFile record {| + *http:Ok; + OpenAIFile body; + map headers; +|}; + public type ListModelsResponse record { "list" 'object; Model[] data; From ada85e3bc09946cd04c4ed5f9eada45f97171d6b Mon Sep 17 00:00:00 2001 From: KATTA-00 Date: Thu, 8 Aug 2024 21:56:38 +0530 Subject: [PATCH 02/36] adding check keyword and removing error handling --- ballerina/tests/test.bal | 331 ++++++++++++--------------------------- 1 file changed, 101 insertions(+), 230 deletions(-) diff --git a/ballerina/tests/test.bal b/ballerina/tests/test.bal index 81874c5..6f6182b 100644 --- a/ballerina/tests/test.bal +++ b/ballerina/tests/test.bal @@ -33,14 +33,10 @@ final string fileName = "sample.jsonl"; @test:Config {} isolated function testListModels() returns error? { - ListModelsResponse|error modelsResponse = check baseClient->/models.get(); - - if (modelsResponse is ListModelsResponse) { - test:assertEquals(modelsResponse.'object, "list", "Object type mismatched"); - test:assertTrue(modelsResponse.hasKey("data"), "Response does not have the key 'data'"); - } else { - return modelsResponse; - } + ListModelsResponse modelsResponse = check baseClient->/models.get(); + + test:assertEquals(modelsResponse.'object, "list", "Object type mismatched"); + test:assertTrue(modelsResponse.hasKey("data"), "Response does not have the key 'data'"); } @test:Config { @@ -48,96 +44,64 @@ isolated function testListModels() returns error? { } isolated function testRetrieveModel() returns error? { - ListModelsResponse|error modelsResponse = check baseClient->/models.get(); + ListModelsResponse modelsResponse = check baseClient->/models.get(); string modelId = "gpt-3.5-turbo"; - if (modelsResponse is ListModelsResponse) { - modelId = modelsResponse.data[0].id; - } else { - return modelsResponse; - } + modelId = modelsResponse.data[0].id; - Model|error modelResponse = baseClient->/models/[modelId].get(); + Model modelResponse = check baseClient->/models/[modelId].get(); - if (modelResponse is Model) { - test:assertEquals(modelResponse.id, modelId, "Model id mismatched"); - test:assertTrue(modelResponse.hasKey("object"), "Response does not have the key 'object'"); - } else { - return modelResponse; - } + test:assertEquals(modelResponse.id, modelId, "Model id mismatched"); + test:assertTrue(modelResponse.hasKey("object"), "Response does not have the key 'object'"); } -// @test:Config { -// dependsOn: [testCreateFineTuningJob, testListModels] -// } -// isolated function testDeleteModel() returns error? { - -// byte[]|error fileContent = io:fileReadBytes(fileName); - -// if (fileContent is error) { -// return fileContent; -// } - -// CreateFileRequest fileRequest = { -// file: {fileContent, fileName}, -// purpose: "fine-tune" -// }; - -// OpenAIFile|error fileResponse = baseClient->/files.post(fileRequest); +@test:Config { + dependsOn: [testCreateFineTuningJob, testListModels] +} +isolated function testDeleteModel() returns error? { -// if (fileResponse is error) { -// return fileResponse; -// } + byte[] fileContent = check io:fileReadBytes(fileName); -// string fileId = fileResponse.id; + CreateFileRequest fileRequest = { + file: {fileContent, fileName}, + purpose: "fine-tune" + }; -// ListModelsResponse|error modelsResponse = baseClient->/models.get(); + OpenAIFile fileResponse = check baseClient->/files.post(fileRequest); -// if (modelsResponse is error) { -// return modelsResponse; -// } + string fileId = fileResponse.id; -// // string modelId = modelsResponse.data[0].id; -// string modelId = "gpt-3.5-turbo"; + ListModelsResponse modelsResponse = check baseClient->/models.get(); -// CreateFineTuningJobRequest fineTuneRequest = { -// model: modelId, -// training_file: fileId -// }; + // string modelId = modelsResponse.data[0].id; + string modelId = "gpt-3.5-turbo"; -// FineTuningJob|error fineTuneResponse = baseClient->/fine_tuning/jobs.post(fineTuneRequest); + CreateFineTuningJobRequest fineTuneRequest = { + model: modelId, + training_file: fileId + }; -// if (fineTuneResponse is error) { -// return fineTuneResponse; -// } + FineTuningJob fineTuneResponse = check baseClient->/fine_tuning/jobs.post(fineTuneRequest); -// string modelIdCreated = fineTuneResponse.model; + string modelIdCreated = fineTuneResponse.model; -// DeleteModelResponse|error modelResponseDelete = baseClient->/models/[modelIdCreated].delete(); + DeleteModelResponse modelResponseDelete = check baseClient->/models/[modelIdCreated].delete(); -// if (modelResponseDelete is DeleteModelResponse) { -// test:assertEquals(modelResponseDelete.id, modelIdCreated, "Model id mismatched"); -// test:assertTrue(modelResponseDelete.hasKey("object"), "Response does not have the key 'object'"); -// } else { -// return modelResponseDelete; -// } -// } + test:assertEquals(modelResponseDelete.id, modelIdCreated, "Model id mismatched"); + test:assertTrue(modelResponseDelete.hasKey("object"), "Response does not have the key 'object'"); +} // // Files @test:Config {} isolated function testListFiles() returns error? { - ListFilesResponse|error filesResponse = baseClient->/files.get(); + ListFilesResponse filesResponse = check baseClient->/files.get(); - if (filesResponse is ListFilesResponse) { - test:assertEquals(filesResponse.'object, "list", "Object type mismatched"); - test:assertTrue(filesResponse.hasKey("data"), "Response does not have the key 'data'"); - } else { - return filesResponse; - } + test:assertEquals(filesResponse.'object, "list", "Object type mismatched"); + test:assertTrue(filesResponse.hasKey("data"), "Response does not have the key 'data'"); } @@ -146,49 +110,32 @@ isolated function testListFiles() returns error? { } isolated function testCreateFile() returns error? { - byte[]|error fileContent = io:fileReadBytes(fileName); - - if (fileContent is error) { - return fileContent; - } + byte[] fileContent = check io:fileReadBytes(fileName); CreateFileRequest fileRequest = { file: {fileContent, fileName}, purpose: "fine-tune" }; - OpenAIFile|error fileResponse = baseClient->/files.post(fileRequest); - - if (fileResponse is error) { - return fileResponse; - } + OpenAIFile fileResponse = check baseClient->/files.post(fileRequest); test:assertEquals(fileResponse.purpose, "fine-tune", "Purpose mismatched"); test:assertTrue(fileResponse.id !is "", "File id is empty"); } @test:Config { - // dependsOn: [testCreateFile] + dependsOn: [testCreateFile] } isolated function testRetrieveFile() returns error? { - ListFilesResponse|error filesResponse = baseClient->/files.get(); - - if (filesResponse is ListFilesResponse) { + ListFilesResponse filesResponse = check baseClient->/files.get(); - string fileId = filesResponse.data[0].id; + string fileId = filesResponse.data[0].id; - OpenAIFile|error fileResponse = baseClient->/files/[fileId].get(); + OpenAIFile fileResponse = check baseClient->/files/[fileId].get(); - if (fileResponse is OpenAIFile) { - test:assertEquals(fileResponse.id, fileId, "File id mismatched"); - test:assertTrue(fileResponse.hasKey("object"), "Response does not have the key 'object'"); - } else { - return fileResponse; - } - } else { - return filesResponse; - } + test:assertEquals(fileResponse.id, fileId, "File id mismatched"); + test:assertTrue(fileResponse.hasKey("object"), "Response does not have the key 'object'"); } @test:Config { @@ -196,79 +143,51 @@ isolated function testRetrieveFile() returns error? { } isolated function testDownloadFile() returns error? { - byte[]|error fileContent = io:fileReadBytes(fileName); - - if (fileContent is error) { - return fileContent; - } + byte[] fileContent = check io:fileReadBytes(fileName); CreateFileRequest fileRequest = { file: {fileContent, fileName}, purpose: "fine-tune" }; - OpenAIFile|error fileResponse = baseClient->/files.post(fileRequest); - - if (fileResponse is error) { - return fileResponse; - } + OpenAIFile fileResponse = check baseClient->/files.post(fileRequest); string fileId = fileResponse.id; - byte[]|error fileContentDownload = baseClient->/files/[fileId]/content.get(); - - if (fileContentDownload is error) { - return fileContentDownload; - } + byte[] fileContentDownload = check baseClient->/files/[fileId]/content.get(); } -// @test:Config { -// dependsOn: [testCreateFile, testRetrieveFile, testListFiles] -// } -// isolated function testDeleteFile() returns error? { - -// byte[]|error fileContent = io:fileReadBytes(fileName); - -// if (fileContent is error) { -// return fileContent; -// } - -// CreateFileRequest fileRequest = { -// file: {fileContent, fileName}, -// purpose: "fine-tune" -// }; - -// OpenAIFile|error fileResponse = baseClient->/files.post(fileRequest); - -// if (fileResponse is error) { -// return fileResponse; -// } - -// string fileId = fileResponse.id; +@test:Config { + dependsOn: [testCreateFile, testRetrieveFile, testListFiles] +} +isolated function testDeleteFile() returns error? { -// DeleteFileResponse|error fileResponseDelete = baseClient->/files/[fileId].delete(); + byte[] fileContent = check io:fileReadBytes(fileName); + + CreateFileRequest fileRequest = { + file: {fileContent, fileName}, + purpose: "fine-tune" + }; -// if (fileResponseDelete is DeleteFileResponse) { -// test:assertEquals(fileResponseDelete.id, fileId, "File id mismatched"); -// test:assertTrue(fileResponseDelete.hasKey("object"), "Response does not have the key 'object'"); -// } else { -// return fileResponseDelete; -// } -// } + OpenAIFile fileResponse = check baseClient->/files.post(fileRequest); + + string fileId = fileResponse.id; + + DeleteFileResponse fileResponseDelete = check baseClient->/files/[fileId].delete(); + + test:assertEquals(fileResponseDelete.id, fileId, "File id mismatched"); + test:assertTrue(fileResponseDelete.hasKey("object"), "Response does not have the key 'object'"); +} // // Fine Tuning Jobs @test:Config {} isolated function testListPaginatedFineTuningJobs() returns error? { - ListPaginatedFineTuningJobsResponse|error jobsResponse = baseClient->/fine_tuning/jobs.get(); + ListPaginatedFineTuningJobsResponse jobsResponse = check baseClient->/fine_tuning/jobs.get(); - if (jobsResponse is ListPaginatedFineTuningJobsResponse) { - test:assertEquals(jobsResponse.'object, "list", "Object type mismatched"); - test:assertTrue(jobsResponse.hasKey("data"), "Response does not have the key 'data'"); - } else { - return jobsResponse; - } + test:assertEquals(jobsResponse.'object, "list", "Object type mismatched"); + test:assertTrue(jobsResponse.hasKey("data"), "Response does not have the key 'data'"); } @test:Config { @@ -276,30 +195,18 @@ isolated function testListPaginatedFineTuningJobs() returns error? { } isolated function testCreateFineTuningJob() returns error? { - byte[]|error fileContent = io:fileReadBytes(fileName); - - if (fileContent is error) { - return fileContent; - } + byte[] fileContent = check io:fileReadBytes(fileName); CreateFileRequest fileRequest = { file: {fileContent, fileName}, purpose: "fine-tune" }; - OpenAIFile|error fileResponse = baseClient->/files.post(fileRequest); - - if (fileResponse is error) { - return fileResponse; - } + OpenAIFile fileResponse = check baseClient->/files.post(fileRequest); string fileId = fileResponse.id; - ListModelsResponse|error modelsResponse = baseClient->/models.get(); - - if (modelsResponse is error) { - return modelsResponse; - } + ListModelsResponse modelsResponse = check baseClient->/models.get(); // string modelId = modelsResponse.data[0].id; string modelId = "gpt-3.5-turbo"; @@ -309,14 +216,10 @@ isolated function testCreateFineTuningJob() returns error? { training_file: fileId }; - FineTuningJob|error fineTuneResponse = baseClient->/fine_tuning/jobs.post(fineTuneRequest); + FineTuningJob fineTuneResponse = check baseClient->/fine_tuning/jobs.post(fineTuneRequest); - if (fineTuneResponse is FineTuningJob) { - test:assertTrue(fineTuneResponse.hasKey("object"), "Response does not have the key 'object'"); - test:assertTrue(fineTuneResponse.hasKey("id"), "Response does not have the key 'id'"); - } else { - return fineTuneResponse; - } + test:assertTrue(fineTuneResponse.hasKey("object"), "Response does not have the key 'object'"); + test:assertTrue(fineTuneResponse.hasKey("id"), "Response does not have the key 'id'"); } @@ -325,22 +228,14 @@ isolated function testCreateFineTuningJob() returns error? { } isolated function testRetrieveFineTuningJob() returns error? { - ListPaginatedFineTuningJobsResponse|error jobsResponse = baseClient->/fine_tuning/jobs.get(); + ListPaginatedFineTuningJobsResponse jobsResponse = check baseClient->/fine_tuning/jobs.get(); - if (jobsResponse is ListPaginatedFineTuningJobsResponse) { - string jobId = jobsResponse.data[0].id; + string jobId = jobsResponse.data[0].id; - FineTuningJob|error jobResponse = baseClient->/fine_tuning/jobs/[jobId].get(); + FineTuningJob jobResponse = check baseClient->/fine_tuning/jobs/[jobId].get(); - if (jobResponse is FineTuningJob) { - test:assertEquals(jobResponse.id, jobId, "Job id mismatched"); - test:assertTrue(jobResponse.hasKey("object"), "Response does not have the key 'object'"); - } else { - return jobResponse; - } - } else { - return jobsResponse; - } + test:assertEquals(jobResponse.id, jobId, "Job id mismatched"); + test:assertTrue(jobResponse.hasKey("object"), "Response does not have the key 'object'"); } @@ -351,22 +246,14 @@ isolated function testListFineTuningEvents() returns error? { string fine_tuning_job_id = "ftjob-qxrbfm03AOBVju8HYytXc0lN"; - ListPaginatedFineTuningJobsResponse|error jobsResponse = baseClient->/fine_tuning/jobs.get(); + ListPaginatedFineTuningJobsResponse jobsResponse = check baseClient->/fine_tuning/jobs.get(); - if (jobsResponse is ListPaginatedFineTuningJobsResponse) { - fine_tuning_job_id = jobsResponse.data[0].id; - } else { - return jobsResponse; - } + fine_tuning_job_id = jobsResponse.data[0].id; - ListFineTuningJobEventsResponse|error eventsResponse = baseClient->/fine_tuning/jobs/[fine_tuning_job_id]/events.get(); + ListFineTuningJobEventsResponse eventsResponse = check baseClient->/fine_tuning/jobs/[fine_tuning_job_id]/events.get(); - if (eventsResponse is ListFineTuningJobEventsResponse) { - test:assertEquals(eventsResponse.'object, "list", "Object type mismatched"); - test:assertTrue(eventsResponse.hasKey("data"), "Response does not have the key 'data'"); - } else { - return eventsResponse; - } + test:assertEquals(eventsResponse.'object, "list", "Object type mismatched"); + test:assertTrue(eventsResponse.hasKey("data"), "Response does not have the key 'data'"); } @@ -377,46 +264,30 @@ isolated function testListFineTuningJobCheckpoints() returns error? { string fine_tuning_job_id = "ftjob-qxrbfm03AOBVju8HYytXc0lN"; - ListPaginatedFineTuningJobsResponse|error jobsResponse = baseClient->/fine_tuning/jobs.get(); + ListPaginatedFineTuningJobsResponse jobsResponse = check baseClient->/fine_tuning/jobs.get(); - if (jobsResponse is ListPaginatedFineTuningJobsResponse) { - fine_tuning_job_id = jobsResponse.data[0].id; - } else { - return jobsResponse; - } + fine_tuning_job_id = jobsResponse.data[0].id; - ListFineTuningJobCheckpointsResponse|error checkpointsResponse = baseClient->/fine_tuning/jobs/[fine_tuning_job_id]/checkpoints.get(); + ListFineTuningJobCheckpointsResponse checkpointsResponse = check baseClient->/fine_tuning/jobs/[fine_tuning_job_id]/checkpoints.get(); - if (checkpointsResponse is ListFineTuningJobCheckpointsResponse) { - test:assertEquals(checkpointsResponse.'object, "list", "Object type mismatched"); - test:assertTrue(checkpointsResponse.hasKey("data"), "Response does not have the key 'data'"); - } else { - return checkpointsResponse; - } + test:assertEquals(checkpointsResponse.'object, "list", "Object type mismatched"); + test:assertTrue(checkpointsResponse.hasKey("data"), "Response does not have the key 'data'"); } -// @test:Config { -// dependsOn: [testCreateFineTuningJob] -// } -// isolated function testCancelFineTuningJob() returns error? { +@test:Config { + dependsOn: [testCreateFineTuningJob] +} +isolated function testCancelFineTuningJob() returns error? { -// string fine_tuning_job_id = "ftjob-qxrbfm03AOBVju8HYytXc0lN"; + string fine_tuning_job_id = "ftjob-qxrbfm03AOBVju8HYytXc0lN"; -// ListPaginatedFineTuningJobsResponse|error jobsResponse = baseClient->/fine_tuning/jobs.get(); + ListPaginatedFineTuningJobsResponse jobsResponse = check baseClient->/fine_tuning/jobs.get(); -// if (jobsResponse is ListPaginatedFineTuningJobsResponse) { -// fine_tuning_job_id = jobsResponse.data[0].id; -// } else { -// return jobsResponse; -// } + fine_tuning_job_id = jobsResponse.data[0].id; -// FineTuningJob|error jobResponse = baseClient->/fine_tuning/jobs/[fine_tuning_job_id]/cancel.post(); + FineTuningJob jobResponse = check baseClient->/fine_tuning/jobs/[fine_tuning_job_id]/cancel.post(); -// if (jobResponse is FineTuningJob) { -// test:assertEquals(jobResponse.id, fine_tuning_job_id, "Job id mismatched"); -// test:assertTrue(jobResponse.hasKey("object"), "Response does not have the key 'object'"); -// } else { -// return jobResponse; -// } -// } \ No newline at end of file + test:assertEquals(jobResponse.id, fine_tuning_job_id, "Job id mismatched"); + test:assertTrue(jobResponse.hasKey("object"), "Response does not have the key 'object'"); +} \ No newline at end of file From 67d4796670c5313bd99ced57a2fac77645297efc Mon Sep 17 00:00:00 2001 From: KATTA-00 Date: Fri, 9 Aug 2024 07:30:11 +0530 Subject: [PATCH 03/36] commenting not implemeted services --- ballerina/tests/test.bal | 100 +++++++++++++++++++-------------------- 1 file changed, 50 insertions(+), 50 deletions(-) diff --git a/ballerina/tests/test.bal b/ballerina/tests/test.bal index 6f6182b..d4be8fa 100644 --- a/ballerina/tests/test.bal +++ b/ballerina/tests/test.bal @@ -57,41 +57,41 @@ isolated function testRetrieveModel() returns error? { } -@test:Config { - dependsOn: [testCreateFineTuningJob, testListModels] -} -isolated function testDeleteModel() returns error? { +// @test:Config { +// dependsOn: [testCreateFineTuningJob, testListModels] +// } +// isolated function testDeleteModel() returns error? { - byte[] fileContent = check io:fileReadBytes(fileName); +// byte[] fileContent = check io:fileReadBytes(fileName); - CreateFileRequest fileRequest = { - file: {fileContent, fileName}, - purpose: "fine-tune" - }; +// CreateFileRequest fileRequest = { +// file: {fileContent, fileName}, +// purpose: "fine-tune" +// }; - OpenAIFile fileResponse = check baseClient->/files.post(fileRequest); +// OpenAIFile fileResponse = check baseClient->/files.post(fileRequest); - string fileId = fileResponse.id; +// string fileId = fileResponse.id; - ListModelsResponse modelsResponse = check baseClient->/models.get(); +// ListModelsResponse modelsResponse = check baseClient->/models.get(); - // string modelId = modelsResponse.data[0].id; - string modelId = "gpt-3.5-turbo"; +// // string modelId = modelsResponse.data[0].id; +// string modelId = "gpt-3.5-turbo"; - CreateFineTuningJobRequest fineTuneRequest = { - model: modelId, - training_file: fileId - }; +// CreateFineTuningJobRequest fineTuneRequest = { +// model: modelId, +// training_file: fileId +// }; - FineTuningJob fineTuneResponse = check baseClient->/fine_tuning/jobs.post(fineTuneRequest); +// FineTuningJob fineTuneResponse = check baseClient->/fine_tuning/jobs.post(fineTuneRequest); - string modelIdCreated = fineTuneResponse.model; +// string modelIdCreated = fineTuneResponse.model; - DeleteModelResponse modelResponseDelete = check baseClient->/models/[modelIdCreated].delete(); +// DeleteModelResponse modelResponseDelete = check baseClient->/models/[modelIdCreated].delete(); - test:assertEquals(modelResponseDelete.id, modelIdCreated, "Model id mismatched"); - test:assertTrue(modelResponseDelete.hasKey("object"), "Response does not have the key 'object'"); -} +// test:assertEquals(modelResponseDelete.id, modelIdCreated, "Model id mismatched"); +// test:assertTrue(modelResponseDelete.hasKey("object"), "Response does not have the key 'object'"); +// } // // Files @@ -157,27 +157,27 @@ isolated function testDownloadFile() returns error? { byte[] fileContentDownload = check baseClient->/files/[fileId]/content.get(); } -@test:Config { - dependsOn: [testCreateFile, testRetrieveFile, testListFiles] -} -isolated function testDeleteFile() returns error? { +// @test:Config { +// dependsOn: [testCreateFile, testRetrieveFile, testListFiles] +// } +// isolated function testDeleteFile() returns error? { - byte[] fileContent = check io:fileReadBytes(fileName); +// byte[] fileContent = check io:fileReadBytes(fileName); - CreateFileRequest fileRequest = { - file: {fileContent, fileName}, - purpose: "fine-tune" - }; +// CreateFileRequest fileRequest = { +// file: {fileContent, fileName}, +// purpose: "fine-tune" +// }; - OpenAIFile fileResponse = check baseClient->/files.post(fileRequest); +// OpenAIFile fileResponse = check baseClient->/files.post(fileRequest); - string fileId = fileResponse.id; +// string fileId = fileResponse.id; - DeleteFileResponse fileResponseDelete = check baseClient->/files/[fileId].delete(); +// DeleteFileResponse fileResponseDelete = check baseClient->/files/[fileId].delete(); - test:assertEquals(fileResponseDelete.id, fileId, "File id mismatched"); - test:assertTrue(fileResponseDelete.hasKey("object"), "Response does not have the key 'object'"); -} +// test:assertEquals(fileResponseDelete.id, fileId, "File id mismatched"); +// test:assertTrue(fileResponseDelete.hasKey("object"), "Response does not have the key 'object'"); +// } // // Fine Tuning Jobs @@ -275,19 +275,19 @@ isolated function testListFineTuningJobCheckpoints() returns error? { } -@test:Config { - dependsOn: [testCreateFineTuningJob] -} -isolated function testCancelFineTuningJob() returns error? { +// @test:Config { +// dependsOn: [testCreateFineTuningJob] +// } +// isolated function testCancelFineTuningJob() returns error? { - string fine_tuning_job_id = "ftjob-qxrbfm03AOBVju8HYytXc0lN"; +// string fine_tuning_job_id = "ftjob-qxrbfm03AOBVju8HYytXc0lN"; - ListPaginatedFineTuningJobsResponse jobsResponse = check baseClient->/fine_tuning/jobs.get(); +// ListPaginatedFineTuningJobsResponse jobsResponse = check baseClient->/fine_tuning/jobs.get(); - fine_tuning_job_id = jobsResponse.data[0].id; +// fine_tuning_job_id = jobsResponse.data[0].id; - FineTuningJob jobResponse = check baseClient->/fine_tuning/jobs/[fine_tuning_job_id]/cancel.post(); +// FineTuningJob jobResponse = check baseClient->/fine_tuning/jobs/[fine_tuning_job_id]/cancel.post(); - test:assertEquals(jobResponse.id, fine_tuning_job_id, "Job id mismatched"); - test:assertTrue(jobResponse.hasKey("object"), "Response does not have the key 'object'"); -} \ No newline at end of file +// test:assertEquals(jobResponse.id, fine_tuning_job_id, "Job id mismatched"); +// test:assertTrue(jobResponse.hasKey("object"), "Response does not have the key 'object'"); +// } \ No newline at end of file From 2417191474aa5eb7db49329b197506c4fc9f31a0 Mon Sep 17 00:00:00 2001 From: KATTA-00 Date: Fri, 9 Aug 2024 10:25:23 +0530 Subject: [PATCH 04/36] Add test for fine-tuning job cancellation and file deletion endpoints --- ballerina/tests/openapi_service.bal | 67 +++++++++++++++++++++++------ ballerina/tests/test.bal | 54 +++++++++++++---------- 2 files changed, 86 insertions(+), 35 deletions(-) diff --git a/ballerina/tests/openapi_service.bal b/ballerina/tests/openapi_service.bal index c87e6c4..7c7c764 100644 --- a/ballerina/tests/openapi_service.bal +++ b/ballerina/tests/openapi_service.bal @@ -24,12 +24,6 @@ listener http:Listener httpListener = new (9090); http:Service mockService = service object { - // # Delete a file. - // # - // # + file_id - The ID of the file to use for this request. - // # + return - OK - // resource function delete files/[string file_id]() returns DeleteFileResponse { - // } // # Delete a fine-tuned model. You must have the Owner role in your organization to delete a model. // # @@ -38,6 +32,61 @@ http:Service mockService = service object { // resource function delete models/[string model]() returns DeleteModelResponse { // } + # Immediately cancel a fine-tune job. + # + # + fine_tuning_job_id - The ID of the fine-tuning job to cancel. + # + return - OK + resource function post fine_tuning/jobs/[string fine_tuning_job_id]/cancel() returns OkFineTuningJob { + + OkFineTuningJob response = { + body:{ + "object": "fine_tuning.job", + "id": fine_tuning_job_id, + "model": "gpt-3.5-turbo-0125", + "created_at": 1723110882, + "finished_at": null, + "fine_tuned_model": null, + "organization_id": "org-Gzp0rlPk9gw4JaNXmPqDJ1H4", + "result_files": [], + "status": "validating_files", + "validation_file": null, + "training_file": "file-JZMH9Xxnt7Hg2io6N2kzmlzM", + "hyperparameters": { + "n_epochs": "auto", + "batch_size": "auto", + "learning_rate_multiplier": "auto" + }, + "trained_tokens": null, + "error": {}, + "user_provided_suffix": null, + "seed": 1776549854, + "estimated_finish": null, + "integrations": [] + }, + headers: { + "Content-Type": "application/json" + } + }; + + return response; + } + + # Delete a file. + # + # + file_id - The ID of the file to use for this request. + # + return - OK + resource function delete files/[string file_id]() returns DeleteFileResponse { + + DeleteFileResponse response = { + 'object: "file", + id: file_id, + deleted: true + }; + + return response; + + } + # Returns a list of files that belong to the user's organization. # # + purpose - Only return files with the given purpose. @@ -369,12 +418,6 @@ http:Service mockService = service object { } - // # Immediately cancel a fine-tune job. - // # - // # + fine_tuning_job_id - The ID of the fine-tuning job to cancel. - // # + return - OK - // resource function post fine_tuning/jobs/[string fine_tuning_job_id]/cancel() returns OkFineTuningJob { - // } }; diff --git a/ballerina/tests/test.bal b/ballerina/tests/test.bal index d4be8fa..cf286c1 100644 --- a/ballerina/tests/test.bal +++ b/ballerina/tests/test.bal @@ -39,9 +39,7 @@ isolated function testListModels() returns error? { test:assertTrue(modelsResponse.hasKey("data"), "Response does not have the key 'data'"); } -@test:Config { - dependsOn: [testListModels] -} +@test:Config {} isolated function testRetrieveModel() returns error? { ListModelsResponse modelsResponse = check baseClient->/models.get(); @@ -58,7 +56,7 @@ isolated function testRetrieveModel() returns error? { } // @test:Config { -// dependsOn: [testCreateFineTuningJob, testListModels] +// dependsOn: [testCreateFineTuningJob, testListModels, testRetrieveModel] // } // isolated function testDeleteModel() returns error? { @@ -121,6 +119,13 @@ isolated function testCreateFile() returns error? { test:assertEquals(fileResponse.purpose, "fine-tune", "Purpose mismatched"); test:assertTrue(fileResponse.id !is "", "File id is empty"); + + string fileId = fileResponse.id; + + DeleteFileResponse fileResponseDelete = check baseClient->/files/[fileId].delete(); + + test:assertEquals(fileResponseDelete.id, fileId, "File id mismatched"); + test:assertTrue(fileResponseDelete.hasKey("object"), "Response does not have the key 'object'"); } @test:Config { @@ -157,27 +162,27 @@ isolated function testDownloadFile() returns error? { byte[] fileContentDownload = check baseClient->/files/[fileId]/content.get(); } -// @test:Config { -// dependsOn: [testCreateFile, testRetrieveFile, testListFiles] -// } -// isolated function testDeleteFile() returns error? { +@test:Config { + dependsOn: [testCreateFile, testRetrieveFile, testListFiles, testDownloadFile] +} +isolated function testDeleteFile() returns error? { -// byte[] fileContent = check io:fileReadBytes(fileName); + byte[] fileContent = check io:fileReadBytes(fileName); -// CreateFileRequest fileRequest = { -// file: {fileContent, fileName}, -// purpose: "fine-tune" -// }; + CreateFileRequest fileRequest = { + file: {fileContent, fileName}, + purpose: "fine-tune" + }; -// OpenAIFile fileResponse = check baseClient->/files.post(fileRequest); + OpenAIFile fileResponse = check baseClient->/files.post(fileRequest); -// string fileId = fileResponse.id; + string fileId = fileResponse.id; -// DeleteFileResponse fileResponseDelete = check baseClient->/files/[fileId].delete(); + DeleteFileResponse fileResponseDelete = check baseClient->/files/[fileId].delete(); -// test:assertEquals(fileResponseDelete.id, fileId, "File id mismatched"); -// test:assertTrue(fileResponseDelete.hasKey("object"), "Response does not have the key 'object'"); -// } + test:assertEquals(fileResponseDelete.id, fileId, "File id mismatched"); + test:assertTrue(fileResponseDelete.hasKey("object"), "Response does not have the key 'object'"); +} // // Fine Tuning Jobs @@ -191,7 +196,7 @@ isolated function testListPaginatedFineTuningJobs() returns error? { } @test:Config { - dependsOn: [testListPaginatedFineTuningJobs, testListModels, testCreateFile, testRetrieveFile, testListFiles] + dependsOn: [testListPaginatedFineTuningJobs, testListModels, testCreateFile, testRetrieveFile, testListFiles, testDownloadFile, testDeleteFile] } isolated function testCreateFineTuningJob() returns error? { @@ -221,6 +226,12 @@ isolated function testCreateFineTuningJob() returns error? { test:assertTrue(fineTuneResponse.hasKey("object"), "Response does not have the key 'object'"); test:assertTrue(fineTuneResponse.hasKey("id"), "Response does not have the key 'id'"); + string fine_tuning_job_id = fineTuneResponse.id; + + FineTuningJob jobResponse = check baseClient->/fine_tuning/jobs/[fine_tuning_job_id]/cancel.post(); + + test:assertEquals(jobResponse.id, fine_tuning_job_id, "Job id mismatched"); + test:assertTrue(jobResponse.hasKey("object"), "Response does not have the key 'object'"); } @test:Config { @@ -236,7 +247,6 @@ isolated function testRetrieveFineTuningJob() returns error? { test:assertEquals(jobResponse.id, jobId, "Job id mismatched"); test:assertTrue(jobResponse.hasKey("object"), "Response does not have the key 'object'"); - } @test:Config { @@ -254,7 +264,6 @@ isolated function testListFineTuningEvents() returns error? { test:assertEquals(eventsResponse.'object, "list", "Object type mismatched"); test:assertTrue(eventsResponse.hasKey("data"), "Response does not have the key 'data'"); - } @test:Config { @@ -272,7 +281,6 @@ isolated function testListFineTuningJobCheckpoints() returns error? { test:assertEquals(checkpointsResponse.'object, "list", "Object type mismatched"); test:assertTrue(checkpointsResponse.hasKey("data"), "Response does not have the key 'data'"); - } // @test:Config { From 95229c702aed813dd6c98a5381a809e156ce8e44 Mon Sep 17 00:00:00 2001 From: KATTA-00 Date: Fri, 9 Aug 2024 11:39:13 +0530 Subject: [PATCH 05/36] Add a README.md for test --- ballerina/tests/README.md | 89 +++++++++++++++++++++++++++++++++++++++ ballerina/tests/test.bal | 5 ++- 2 files changed, 92 insertions(+), 2 deletions(-) create mode 100644 ballerina/tests/README.md diff --git a/ballerina/tests/README.md b/ballerina/tests/README.md new file mode 100644 index 0000000..cca0034 --- /dev/null +++ b/ballerina/tests/README.md @@ -0,0 +1,89 @@ +# Running Tests + +## Prerequisites + +You need an API token from OpenAI. + +To obtain this, refer to the [Ballerina OpenAI Finetunes Connector](https://github.com/ballerina-platform/module-ballerinax-openai.finetunes/blob/main/ballerina/Module.md). + +## Test Environments + +There are two test environments for running the `openai.finetunes` connector tests. The default environment is a mock server for the OpenAI API. The other environment is the actual OpenAI API. + +You can run the tests in either of these environments, and each has its own compatible set of tests. + +| Test Groups | Environment | +|-------------|---------------------------------------------------| +| mock_tests | Mock server for OpenAI API (Default Environment) | +| live_tests | OpenAI API | + +## Running Tests in the Mock Server + +To execute the tests on the mock server, ensure that the `isLiveServer` environment variable is either set to `false` or left unset before initiating the tests. + +This environment variable can be configured within the `Config.toml` file located in the `tests` directory or specified as an environment variable. + +### Using a `Config.toml` File + +Create a `Config.toml` file in the `tests` directory with the following content: + +```toml +isLiveServer = false +``` + +### Using Environment Variables + +Alternatively, you can set the environment variable directly. + +For Linux or macOS: + +```bash +export isLiveServer=false +``` + +For Windows: + +```bash +setx isLiveServer false +``` + +Then, run the following command to execute the tests: + +```bash +./gradlew clean test +``` + +## Running Tests Against the OpenAI Live API + +### Using a `Config.toml` File + +Create a `Config.toml` file in the `tests` directory and add your authentication credentials: + +```toml +isLiveServer = true +token = "" +``` + +### Using Environment Variables + +Alternatively, you can set your authentication credentials as environment variables. + +For Linux or macOS: + +```bash +export isLiveServer=true +export token="" +``` + +For Windows: + +```bash +setx isLiveServer true +setx token +``` + +Then, run the following command to execute the tests: + +```bash +./gradlew clean test +``` \ No newline at end of file diff --git a/ballerina/tests/test.bal b/ballerina/tests/test.bal index cf286c1..fd03d88 100644 --- a/ballerina/tests/test.bal +++ b/ballerina/tests/test.bal @@ -23,8 +23,9 @@ import ballerina/io; configurable boolean isLiveServer = ?; configurable string token = ?; configurable string serviceUrl = isLiveServer ? "https://api.openai.com/v1" : "http://localhost:9090"; -final ConnectionConfig config = {auth: {token}}; +configurable string apiKey = isLiveServer ? token : ""; +final ConnectionConfig config = {auth: {token: apiKey}}; final Client baseClient = check new Client(config, serviceUrl); final string fileName = "sample.jsonl"; @@ -246,7 +247,7 @@ isolated function testRetrieveFineTuningJob() returns error? { FineTuningJob jobResponse = check baseClient->/fine_tuning/jobs/[jobId].get(); test:assertEquals(jobResponse.id, jobId, "Job id mismatched"); - test:assertTrue(jobResponse.hasKey("object"), "Response does not have the key 'object'"); + test:assertEquals(jobResponse.'object, "fine_tuning.job", "Response does not have the key 'object'"); } @test:Config { From 868ea36bf65d6e612d6feac2ab3119721c313274 Mon Sep 17 00:00:00 2001 From: KATTA-00 Date: Fri, 9 Aug 2024 14:33:14 +0530 Subject: [PATCH 06/36] Replace io.fileReadBytes with a byte array --- ballerina/Dependencies.toml | 4 ---- ballerina/tests/test.bal | 13 ++++--------- {ballerina => docs/setup/resources}/sample.jsonl | 0 3 files changed, 4 insertions(+), 13 deletions(-) rename {ballerina => docs/setup/resources}/sample.jsonl (100%) diff --git a/ballerina/Dependencies.toml b/ballerina/Dependencies.toml index 3877ff3..8aad8b8 100644 --- a/ballerina/Dependencies.toml +++ b/ballerina/Dependencies.toml @@ -98,9 +98,6 @@ dependencies = [ {org = "ballerina", name = "jballerina.java"}, {org = "ballerina", name = "lang.value"} ] -modules = [ - {org = "ballerina", packageName = "io", moduleName = "io"} -] [[package]] org = "ballerina" @@ -321,7 +318,6 @@ name = "openai.finetunes" version = "1.0.5" dependencies = [ {org = "ballerina", name = "http"}, - {org = "ballerina", name = "io"}, {org = "ballerina", name = "log"}, {org = "ballerina", name = "mime"}, {org = "ballerina", name = "test"}, diff --git a/ballerina/tests/test.bal b/ballerina/tests/test.bal index fd03d88..7334ee1 100644 --- a/ballerina/tests/test.bal +++ b/ballerina/tests/test.bal @@ -18,7 +18,7 @@ // under the License. import ballerina/test; -import ballerina/io; +// import ballerina/io; configurable boolean isLiveServer = ?; configurable string token = ?; @@ -27,7 +27,10 @@ configurable string apiKey = isLiveServer ? token : ""; final ConnectionConfig config = {auth: {token: apiKey}}; final Client baseClient = check new Client(config, serviceUrl); + final string fileName = "sample.jsonl"; +const string fileId = "file-1"; +const byte[] fileContent = [123,13,10,32,32,32,32,34,112,114,111,109,112,116,34,58,32,34,87,104,97,116,32,105,115,32,116,104,101,32,97,110,115,119,101,114,32,116,111,32,50,43,50,34,44,13,10,32,32,32,32,34,99,111,109,112,108,101,116,105,111,110,34,58,32,34,52,34,13,10,125]; // Models @@ -109,8 +112,6 @@ isolated function testListFiles() returns error? { } isolated function testCreateFile() returns error? { - byte[] fileContent = check io:fileReadBytes(fileName); - CreateFileRequest fileRequest = { file: {fileContent, fileName}, purpose: "fine-tune" @@ -149,8 +150,6 @@ isolated function testRetrieveFile() returns error? { } isolated function testDownloadFile() returns error? { - byte[] fileContent = check io:fileReadBytes(fileName); - CreateFileRequest fileRequest = { file: {fileContent, fileName}, purpose: "fine-tune" @@ -168,8 +167,6 @@ isolated function testDownloadFile() returns error? { } isolated function testDeleteFile() returns error? { - byte[] fileContent = check io:fileReadBytes(fileName); - CreateFileRequest fileRequest = { file: {fileContent, fileName}, purpose: "fine-tune" @@ -201,8 +198,6 @@ isolated function testListPaginatedFineTuningJobs() returns error? { } isolated function testCreateFineTuningJob() returns error? { - byte[] fileContent = check io:fileReadBytes(fileName); - CreateFileRequest fileRequest = { file: {fileContent, fileName}, purpose: "fine-tune" diff --git a/ballerina/sample.jsonl b/docs/setup/resources/sample.jsonl similarity index 100% rename from ballerina/sample.jsonl rename to docs/setup/resources/sample.jsonl From 94f3c8e4fb4746bb8848777840fb4b29c90ffa83 Mon Sep 17 00:00:00 2001 From: KATTA-00 Date: Fri, 9 Aug 2024 15:38:50 +0530 Subject: [PATCH 07/36] Update test cases using moduler var --- ballerina/tests/test.bal | 205 +++++++++++++++------------------------ 1 file changed, 80 insertions(+), 125 deletions(-) diff --git a/ballerina/tests/test.bal b/ballerina/tests/test.bal index 7334ee1..1651815 100644 --- a/ballerina/tests/test.bal +++ b/ballerina/tests/test.bal @@ -29,28 +29,45 @@ final ConnectionConfig config = {auth: {token: apiKey}}; final Client baseClient = check new Client(config, serviceUrl); final string fileName = "sample.jsonl"; -const string fileId = "file-1"; const byte[] fileContent = [123,13,10,32,32,32,32,34,112,114,111,109,112,116,34,58,32,34,87,104,97,116,32,105,115,32,116,104,101,32,97,110,115,119,101,114,32,116,111,32,50,43,50,34,44,13,10,32,32,32,32,34,99,111,109,112,108,101,116,105,111,110,34,58,32,34,52,34,13,10,125]; +public type TestData record { + + string fileId; + string modelId; + string jobId; + +}; + +TestData testData = {fileId: "", modelId: "", jobId: ""}; + +function dataGen() returns TestData[][] { + return [[testData]]; +} + // Models -@test:Config {} -isolated function testListModels() returns error? { +@test:Config { + dataProvider: dataGen +} +isolated function testListModels(TestData testData) returns error? { ListModelsResponse modelsResponse = check baseClient->/models.get(); + // testData.modelId = modelsResponse.data[0].id; + testData.modelId = "gpt-3.5-turbo"; + test:assertEquals(modelsResponse.'object, "list", "Object type mismatched"); test:assertTrue(modelsResponse.hasKey("data"), "Response does not have the key 'data'"); } -@test:Config {} -isolated function testRetrieveModel() returns error? { - - ListModelsResponse modelsResponse = check baseClient->/models.get(); - - string modelId = "gpt-3.5-turbo"; +@test:Config { + dataProvider: dataGen, + dependsOn: [testListModels] +} +isolated function testRetrieveModel(TestData testData) returns error? { - modelId = modelsResponse.data[0].id; + string modelId = testData.modelId; Model modelResponse = check baseClient->/models/[modelId].get(); @@ -60,34 +77,12 @@ isolated function testRetrieveModel() returns error? { } // @test:Config { -// dependsOn: [testCreateFineTuningJob, testListModels, testRetrieveModel] +// dependsOn: [testCreateFineTuningJob, testListModels, testRetrieveModel, testListFineTuningJobCheckpoints, testListFineTuningEvents], +// dataProvider: dataGen // } -// isolated function testDeleteModel() returns error? { - -// byte[] fileContent = check io:fileReadBytes(fileName); - -// CreateFileRequest fileRequest = { -// file: {fileContent, fileName}, -// purpose: "fine-tune" -// }; - -// OpenAIFile fileResponse = check baseClient->/files.post(fileRequest); - -// string fileId = fileResponse.id; - -// ListModelsResponse modelsResponse = check baseClient->/models.get(); +// isolated function testDeleteModel(TestData testData) returns error? { -// // string modelId = modelsResponse.data[0].id; -// string modelId = "gpt-3.5-turbo"; - -// CreateFineTuningJobRequest fineTuneRequest = { -// model: modelId, -// training_file: fileId -// }; - -// FineTuningJob fineTuneResponse = check baseClient->/fine_tuning/jobs.post(fineTuneRequest); - -// string modelIdCreated = fineTuneResponse.model; +// string modelIdCreated = testData.modelId; // DeleteModelResponse modelResponseDelete = check baseClient->/models/[modelIdCreated].delete(); @@ -95,7 +90,7 @@ isolated function testRetrieveModel() returns error? { // test:assertTrue(modelResponseDelete.hasKey("object"), "Response does not have the key 'object'"); // } -// // Files +// Files @test:Config {} isolated function testListFiles() returns error? { @@ -108,9 +103,10 @@ isolated function testListFiles() returns error? { } @test:Config { - dependsOn: [testListFiles] + dependsOn: [testListFiles], + dataProvider: dataGen } -isolated function testCreateFile() returns error? { +isolated function testCreateFile(TestData testData) returns error? { CreateFileRequest fileRequest = { file: {fileContent, fileName}, @@ -118,63 +114,47 @@ isolated function testCreateFile() returns error? { }; OpenAIFile fileResponse = check baseClient->/files.post(fileRequest); + + testData.fileId = fileResponse.id; test:assertEquals(fileResponse.purpose, "fine-tune", "Purpose mismatched"); test:assertTrue(fileResponse.id !is "", "File id is empty"); - string fileId = fileResponse.id; - - DeleteFileResponse fileResponseDelete = check baseClient->/files/[fileId].delete(); - - test:assertEquals(fileResponseDelete.id, fileId, "File id mismatched"); - test:assertTrue(fileResponseDelete.hasKey("object"), "Response does not have the key 'object'"); } @test:Config { - dependsOn: [testCreateFile] + dependsOn: [testCreateFile], + dataProvider: dataGen } -isolated function testRetrieveFile() returns error? { - - ListFilesResponse filesResponse = check baseClient->/files.get(); +isolated function testRetrieveFile(TestData testData) returns error? { - string fileId = filesResponse.data[0].id; + string fileId = testData.fileId; OpenAIFile fileResponse = check baseClient->/files/[fileId].get(); test:assertEquals(fileResponse.id, fileId, "File id mismatched"); test:assertTrue(fileResponse.hasKey("object"), "Response does not have the key 'object'"); + } @test:Config { - dependsOn: [testCreateFile, testRetrieveFile, testListFiles] + dependsOn: [testCreateFile], + dataProvider: dataGen } -isolated function testDownloadFile() returns error? { - - CreateFileRequest fileRequest = { - file: {fileContent, fileName}, - purpose: "fine-tune" - }; - - OpenAIFile fileResponse = check baseClient->/files.post(fileRequest); +isolated function testDownloadFile(TestData testData) returns error? { - string fileId = fileResponse.id; + string fileId = testData.fileId; byte[] fileContentDownload = check baseClient->/files/[fileId]/content.get(); } @test:Config { - dependsOn: [testCreateFile, testRetrieveFile, testListFiles, testDownloadFile] + dependsOn: [testCreateFile, testRetrieveFile, testDownloadFile, testCreateFineTuningJob], + dataProvider: dataGen } -isolated function testDeleteFile() returns error? { +isolated function testDeleteFile(TestData testData) returns error? { - CreateFileRequest fileRequest = { - file: {fileContent, fileName}, - purpose: "fine-tune" - }; - - OpenAIFile fileResponse = check baseClient->/files.post(fileRequest); - - string fileId = fileResponse.id; + string fileId = testData.fileId; DeleteFileResponse fileResponseDelete = check baseClient->/files/[fileId].delete(); @@ -194,23 +174,13 @@ isolated function testListPaginatedFineTuningJobs() returns error? { } @test:Config { - dependsOn: [testListPaginatedFineTuningJobs, testListModels, testCreateFile, testRetrieveFile, testListFiles, testDownloadFile, testDeleteFile] + dependsOn: [testListModels, testCreateFile], + dataProvider: dataGen } -isolated function testCreateFineTuningJob() returns error? { - - CreateFileRequest fileRequest = { - file: {fileContent, fileName}, - purpose: "fine-tune" - }; - - OpenAIFile fileResponse = check baseClient->/files.post(fileRequest); - - string fileId = fileResponse.id; - - ListModelsResponse modelsResponse = check baseClient->/models.get(); - - // string modelId = modelsResponse.data[0].id; - string modelId = "gpt-3.5-turbo"; +isolated function testCreateFineTuningJob(TestData testData) returns error? { + + string fileId = testData.fileId; + string modelId = testData.modelId; CreateFineTuningJobRequest fineTuneRequest = { model: modelId, @@ -218,26 +188,20 @@ isolated function testCreateFineTuningJob() returns error? { }; FineTuningJob fineTuneResponse = check baseClient->/fine_tuning/jobs.post(fineTuneRequest); + + testData.jobId = fineTuneResponse.id; test:assertTrue(fineTuneResponse.hasKey("object"), "Response does not have the key 'object'"); test:assertTrue(fineTuneResponse.hasKey("id"), "Response does not have the key 'id'"); - - string fine_tuning_job_id = fineTuneResponse.id; - - FineTuningJob jobResponse = check baseClient->/fine_tuning/jobs/[fine_tuning_job_id]/cancel.post(); - - test:assertEquals(jobResponse.id, fine_tuning_job_id, "Job id mismatched"); - test:assertTrue(jobResponse.hasKey("object"), "Response does not have the key 'object'"); } @test:Config { - dependsOn: [testCreateFineTuningJob] + dependsOn: [testCreateFineTuningJob], + dataProvider: dataGen } -isolated function testRetrieveFineTuningJob() returns error? { - - ListPaginatedFineTuningJobsResponse jobsResponse = check baseClient->/fine_tuning/jobs.get(); +isolated function testRetrieveFineTuningJob(TestData testData) returns error? { - string jobId = jobsResponse.data[0].id; + string jobId = testData.jobId; FineTuningJob jobResponse = check baseClient->/fine_tuning/jobs/[jobId].get(); @@ -246,15 +210,12 @@ isolated function testRetrieveFineTuningJob() returns error? { } @test:Config { - dependsOn: [testCreateFineTuningJob] + dependsOn: [testCreateFineTuningJob], + dataProvider: dataGen } -isolated function testListFineTuningEvents() returns error? { +isolated function testListFineTuningEvents(TestData testData) returns error? { - string fine_tuning_job_id = "ftjob-qxrbfm03AOBVju8HYytXc0lN"; - - ListPaginatedFineTuningJobsResponse jobsResponse = check baseClient->/fine_tuning/jobs.get(); - - fine_tuning_job_id = jobsResponse.data[0].id; + string fine_tuning_job_id = testData.jobId; ListFineTuningJobEventsResponse eventsResponse = check baseClient->/fine_tuning/jobs/[fine_tuning_job_id]/events.get(); @@ -263,15 +224,12 @@ isolated function testListFineTuningEvents() returns error? { } @test:Config { - dependsOn: [testCreateFineTuningJob] + dependsOn: [testCreateFineTuningJob], + dataProvider: dataGen } -isolated function testListFineTuningJobCheckpoints() returns error? { - - string fine_tuning_job_id = "ftjob-qxrbfm03AOBVju8HYytXc0lN"; - - ListPaginatedFineTuningJobsResponse jobsResponse = check baseClient->/fine_tuning/jobs.get(); +isolated function testListFineTuningJobCheckpoints(TestData testData) returns error? { - fine_tuning_job_id = jobsResponse.data[0].id; + string fine_tuning_job_id = testData.jobId; ListFineTuningJobCheckpointsResponse checkpointsResponse = check baseClient->/fine_tuning/jobs/[fine_tuning_job_id]/checkpoints.get(); @@ -279,19 +237,16 @@ isolated function testListFineTuningJobCheckpoints() returns error? { test:assertTrue(checkpointsResponse.hasKey("data"), "Response does not have the key 'data'"); } -// @test:Config { -// dependsOn: [testCreateFineTuningJob] -// } -// isolated function testCancelFineTuningJob() returns error? { - -// string fine_tuning_job_id = "ftjob-qxrbfm03AOBVju8HYytXc0lN"; - -// ListPaginatedFineTuningJobsResponse jobsResponse = check baseClient->/fine_tuning/jobs.get(); +@test:Config { + dependsOn: [testCreateFineTuningJob], + dataProvider: dataGen +} +isolated function testCancelFineTuningJob(TestData testData) returns error? { -// fine_tuning_job_id = jobsResponse.data[0].id; + string fine_tuning_job_id = testData.jobId; -// FineTuningJob jobResponse = check baseClient->/fine_tuning/jobs/[fine_tuning_job_id]/cancel.post(); + FineTuningJob jobResponse = check baseClient->/fine_tuning/jobs/[fine_tuning_job_id]/cancel.post(); -// test:assertEquals(jobResponse.id, fine_tuning_job_id, "Job id mismatched"); -// test:assertTrue(jobResponse.hasKey("object"), "Response does not have the key 'object'"); -// } \ No newline at end of file + test:assertEquals(jobResponse.id, fine_tuning_job_id, "Job id mismatched"); + test:assertTrue(jobResponse.hasKey("object"), "Response does not have the key 'object'"); +} \ No newline at end of file From 48e789b3cab08700c67033fe853fccefa89c311b Mon Sep 17 00:00:00 2001 From: KATTA-00 Date: Fri, 9 Aug 2024 16:42:12 +0530 Subject: [PATCH 08/36] update test.bal --- ballerina/tests/openapi_service.bal | 20 ++++++++++++++------ ballerina/tests/test.bal | 27 ++++++++++++++------------- 2 files changed, 28 insertions(+), 19 deletions(-) diff --git a/ballerina/tests/openapi_service.bal b/ballerina/tests/openapi_service.bal index 7c7c764..48fc3ec 100644 --- a/ballerina/tests/openapi_service.bal +++ b/ballerina/tests/openapi_service.bal @@ -25,12 +25,20 @@ listener http:Listener httpListener = new (9090); http:Service mockService = service object { - // # Delete a fine-tuned model. You must have the Owner role in your organization to delete a model. - // # - // # + model - The model to delete - // # + return - OK - // resource function delete models/[string model]() returns DeleteModelResponse { - // } + # Delete a fine-tuned model. You must have the Owner role in your organization to delete a model. + # + # + model - The model to delete + # + return - OK + resource function delete models/[string model]() returns DeleteModelResponse { + + DeleteModelResponse response = { + 'object: "model", + id: model, + deleted: true + }; + + return response; + } # Immediately cancel a fine-tune job. # diff --git a/ballerina/tests/test.bal b/ballerina/tests/test.bal index 1651815..be14bf9 100644 --- a/ballerina/tests/test.bal +++ b/ballerina/tests/test.bal @@ -18,7 +18,6 @@ // under the License. import ballerina/test; -// import ballerina/io; configurable boolean isLiveServer = ?; configurable string token = ?; @@ -76,19 +75,20 @@ isolated function testRetrieveModel(TestData testData) returns error? { } -// @test:Config { -// dependsOn: [testCreateFineTuningJob, testListModels, testRetrieveModel, testListFineTuningJobCheckpoints, testListFineTuningEvents], -// dataProvider: dataGen -// } -// isolated function testDeleteModel(TestData testData) returns error? { +@test:Config { + dependsOn: [testCreateFineTuningJob, testListModels, testRetrieveModel, testListFineTuningJobCheckpoints, testListFineTuningEvents], + dataProvider: dataGen, + enable: isLiveServer? false : true +} +isolated function testDeleteModel(TestData testData) returns error? { -// string modelIdCreated = testData.modelId; + string modelIdCreated = testData.modelId; -// DeleteModelResponse modelResponseDelete = check baseClient->/models/[modelIdCreated].delete(); + DeleteModelResponse modelResponseDelete = check baseClient->/models/[modelIdCreated].delete(); -// test:assertEquals(modelResponseDelete.id, modelIdCreated, "Model id mismatched"); -// test:assertTrue(modelResponseDelete.hasKey("object"), "Response does not have the key 'object'"); -// } + test:assertEquals(modelResponseDelete.id, modelIdCreated, "Model id mismatched"); + test:assertTrue(modelResponseDelete.hasKey("object"), "Response does not have the key 'object'"); +} // Files @@ -162,7 +162,7 @@ isolated function testDeleteFile(TestData testData) returns error? { test:assertTrue(fileResponseDelete.hasKey("object"), "Response does not have the key 'object'"); } -// // Fine Tuning Jobs +// Fine Tuning Jobs @test:Config {} isolated function testListPaginatedFineTuningJobs() returns error? { @@ -239,7 +239,8 @@ isolated function testListFineTuningJobCheckpoints(TestData testData) returns er @test:Config { dependsOn: [testCreateFineTuningJob], - dataProvider: dataGen + dataProvider: dataGen, + enable: isLiveServer? false : true } isolated function testCancelFineTuningJob(TestData testData) returns error? { From 168de9f512fc8a570f37b6fde651c73d2797a1cf Mon Sep 17 00:00:00 2001 From: KATTA-00 Date: Mon, 12 Aug 2024 07:42:24 +0530 Subject: [PATCH 09/36] refractor the test.bal --- ballerina/tests/openapi_service.bal | 1 - ballerina/tests/test.bal | 91 +++++++++++++++++++++-------- 2 files changed, 68 insertions(+), 24 deletions(-) diff --git a/ballerina/tests/openapi_service.bal b/ballerina/tests/openapi_service.bal index 48fc3ec..0e90ed5 100644 --- a/ballerina/tests/openapi_service.bal +++ b/ballerina/tests/openapi_service.bal @@ -428,7 +428,6 @@ http:Service mockService = service object { }; - function init() returns error? { if isLiveServer { diff --git a/ballerina/tests/test.bal b/ballerina/tests/test.bal index be14bf9..2650606 100644 --- a/ballerina/tests/test.bal +++ b/ballerina/tests/test.bal @@ -19,235 +19,280 @@ import ballerina/test; +// Configurable variables for environment setup. configurable boolean isLiveServer = ?; configurable string token = ?; configurable string serviceUrl = isLiveServer ? "https://api.openai.com/v1" : "http://localhost:9090"; configurable string apiKey = isLiveServer ? token : ""; +// Initialize the connection configuration and client. final ConnectionConfig config = {auth: {token: apiKey}}; final Client baseClient = check new Client(config, serviceUrl); +// Define sample file content and name. final string fileName = "sample.jsonl"; const byte[] fileContent = [123,13,10,32,32,32,32,34,112,114,111,109,112,116,34,58,32,34,87,104,97,116,32,105,115,32,116,104,101,32,97,110,115,119,101,114,32,116,111,32,50,43,50,34,44,13,10,32,32,32,32,34,99,111,109,112,108,101,116,105,111,110,34,58,32,34,52,34,13,10,125]; +// Record type to hold test data. public type TestData record { - string fileId; string modelId; string jobId; - }; +// Initialize test data. TestData testData = {fileId: "", modelId: "", jobId: ""}; +// Function to generate test data. function dataGen() returns TestData[][] { return [[testData]]; } -// Models - +// Test case to list models. @test:Config { dataProvider: dataGen } + isolated function testListModels(TestData testData) returns error? { + // Fetch the list of models from the API. ListModelsResponse modelsResponse = check baseClient->/models.get(); - // testData.modelId = modelsResponse.data[0].id; + // Set modelId for further testing (hardcoded for demonstration). testData.modelId = "gpt-3.5-turbo"; + // Assertions to verify response correctness. test:assertEquals(modelsResponse.'object, "list", "Object type mismatched"); test:assertTrue(modelsResponse.hasKey("data"), "Response does not have the key 'data'"); } +// Test case to retrieve a specific model by ID. @test:Config { dataProvider: dataGen, dependsOn: [testListModels] } isolated function testRetrieveModel(TestData testData) returns error? { + // Retrieve the model using the model ID. string modelId = testData.modelId; - Model modelResponse = check baseClient->/models/[modelId].get(); + // Assertions to verify response correctness. test:assertEquals(modelResponse.id, modelId, "Model id mismatched"); test:assertTrue(modelResponse.hasKey("object"), "Response does not have the key 'object'"); - } +// Test case to delete a model. @test:Config { dependsOn: [testCreateFineTuningJob, testListModels, testRetrieveModel, testListFineTuningJobCheckpoints, testListFineTuningEvents], dataProvider: dataGen, - enable: isLiveServer? false : true + enable: isLiveServer? false : true // Enable this test only for mock server. } isolated function testDeleteModel(TestData testData) returns error? { + // Delete the model using the model ID. string modelIdCreated = testData.modelId; - DeleteModelResponse modelResponseDelete = check baseClient->/models/[modelIdCreated].delete(); + // Assertions to verify response correctness. test:assertEquals(modelResponseDelete.id, modelIdCreated, "Model id mismatched"); test:assertTrue(modelResponseDelete.hasKey("object"), "Response does not have the key 'object'"); } // Files - +// Test case to list all files. @test:Config {} isolated function testListFiles() returns error? { + // Fetch the list of files from the API. ListFilesResponse filesResponse = check baseClient->/files.get(); + // Assertions to verify response correctness. test:assertEquals(filesResponse.'object, "list", "Object type mismatched"); test:assertTrue(filesResponse.hasKey("data"), "Response does not have the key 'data'"); - } +// Test case to create a new file. @test:Config { dependsOn: [testListFiles], dataProvider: dataGen } isolated function testCreateFile(TestData testData) returns error? { + // Prepare the request to create a new file. CreateFileRequest fileRequest = { file: {fileContent, fileName}, purpose: "fine-tune" }; + // Send the request to create the file. OpenAIFile fileResponse = check baseClient->/files.post(fileRequest); - + + // Store the file ID for subsequent tests. testData.fileId = fileResponse.id; + // Assertions to verify response correctness. test:assertEquals(fileResponse.purpose, "fine-tune", "Purpose mismatched"); test:assertTrue(fileResponse.id !is "", "File id is empty"); - } +// Test case to retrieve details of a specific file. @test:Config { dependsOn: [testCreateFile], dataProvider: dataGen } isolated function testRetrieveFile(TestData testData) returns error? { + // Retrieve the file details using the file ID. string fileId = testData.fileId; - OpenAIFile fileResponse = check baseClient->/files/[fileId].get(); + // Assertions to verify response correctness. test:assertEquals(fileResponse.id, fileId, "File id mismatched"); test:assertTrue(fileResponse.hasKey("object"), "Response does not have the key 'object'"); - } +// Test case to download a file's content. @test:Config { dependsOn: [testCreateFile], dataProvider: dataGen } isolated function testDownloadFile(TestData testData) returns error? { + // Download the content of the file using the file ID. string fileId = testData.fileId; - byte[] fileContentDownload = check baseClient->/files/[fileId]/content.get(); + + // Assertions to verify response correctness. + test:assertFalse(fileContentDownload.length() <= 0, "File content is empty"); + } +// Test case to delete a specific file. @test:Config { dependsOn: [testCreateFile, testRetrieveFile, testDownloadFile, testCreateFineTuningJob], dataProvider: dataGen } isolated function testDeleteFile(TestData testData) returns error? { + // Delete the file using the file ID. string fileId = testData.fileId; - DeleteFileResponse fileResponseDelete = check baseClient->/files/[fileId].delete(); + // Assertions to verify response correctness. test:assertEquals(fileResponseDelete.id, fileId, "File id mismatched"); test:assertTrue(fileResponseDelete.hasKey("object"), "Response does not have the key 'object'"); } -// Fine Tuning Jobs +// Fine Tuning Jobs +// Test case to list all fine-tuning jobs with pagination. @test:Config {} isolated function testListPaginatedFineTuningJobs() returns error? { + // Fetch the list of fine-tuning jobs from the API. ListPaginatedFineTuningJobsResponse jobsResponse = check baseClient->/fine_tuning/jobs.get(); + // Assertions to verify response correctness. test:assertEquals(jobsResponse.'object, "list", "Object type mismatched"); test:assertTrue(jobsResponse.hasKey("data"), "Response does not have the key 'data'"); } +// Test case to create a new fine-tuning job. @test:Config { dependsOn: [testListModels, testCreateFile], dataProvider: dataGen } isolated function testCreateFineTuningJob(TestData testData) returns error? { - + + // Retrieve the file ID and model ID from the test data. string fileId = testData.fileId; string modelId = testData.modelId; + // Prepare the request to create a fine-tuning job. CreateFineTuningJobRequest fineTuneRequest = { model: modelId, training_file: fileId }; + // Send the request to create the fine-tuning job. FineTuningJob fineTuneResponse = check baseClient->/fine_tuning/jobs.post(fineTuneRequest); + // Store the job ID for subsequent tests. testData.jobId = fineTuneResponse.id; - + + // Assertions to verify response correctness. test:assertTrue(fineTuneResponse.hasKey("object"), "Response does not have the key 'object'"); test:assertTrue(fineTuneResponse.hasKey("id"), "Response does not have the key 'id'"); } +// Test case to retrieve details of a specific fine-tuning job. @test:Config { dependsOn: [testCreateFineTuningJob], dataProvider: dataGen } isolated function testRetrieveFineTuningJob(TestData testData) returns error? { + // Retrieve the fine-tuning job details using the job ID. string jobId = testData.jobId; - FineTuningJob jobResponse = check baseClient->/fine_tuning/jobs/[jobId].get(); + // Assertions to verify response correctness. test:assertEquals(jobResponse.id, jobId, "Job id mismatched"); test:assertEquals(jobResponse.'object, "fine_tuning.job", "Response does not have the key 'object'"); } +// Test case to list events associated with a fine-tuning job. @test:Config { dependsOn: [testCreateFineTuningJob], dataProvider: dataGen } isolated function testListFineTuningEvents(TestData testData) returns error? { + // Retrieve the fine-tuning job ID from the test data. string fine_tuning_job_id = testData.jobId; + // Fetch the list of events for the fine-tuning job. ListFineTuningJobEventsResponse eventsResponse = check baseClient->/fine_tuning/jobs/[fine_tuning_job_id]/events.get(); + // Assertions to verify response correctness. test:assertEquals(eventsResponse.'object, "list", "Object type mismatched"); test:assertTrue(eventsResponse.hasKey("data"), "Response does not have the key 'data'"); } +// Test case to list checkpoints of a fine-tuning job. @test:Config { dependsOn: [testCreateFineTuningJob], dataProvider: dataGen } isolated function testListFineTuningJobCheckpoints(TestData testData) returns error? { + // Retrieve the fine-tuning job ID from the test data. string fine_tuning_job_id = testData.jobId; - ListFineTuningJobCheckpointsResponse checkpointsResponse = check baseClient->/fine_tuning/jobs/[fine_tuning_job_id]/checkpoints.get(); + // Fetch the list of checkpoints for the fine-tuning job. + ListFineTuningJobCheckpointsResponse checkpointsResponse = check baseClient->/fine_tuning/jobs/[fine_tuning_job_id]/checkpoints.get(); + // Assertions to verify response correctness. test:assertEquals(checkpointsResponse.'object, "list", "Object type mismatched"); test:assertTrue(checkpointsResponse.hasKey("data"), "Response does not have the key 'data'"); } +// Test case to cancel a fine-tuning job. @test:Config { dependsOn: [testCreateFineTuningJob], dataProvider: dataGen, - enable: isLiveServer? false : true + enable: isLiveServer? false : true // Enable this test only for mock server. } isolated function testCancelFineTuningJob(TestData testData) returns error? { + // Retrieve the fine-tuning job ID from the test data. string fine_tuning_job_id = testData.jobId; + // Send the request to cancel the fine-tuning job. FineTuningJob jobResponse = check baseClient->/fine_tuning/jobs/[fine_tuning_job_id]/cancel.post(); + // Assertions to verify response correctness. test:assertEquals(jobResponse.id, fine_tuning_job_id, "Job id mismatched"); test:assertTrue(jobResponse.hasKey("object"), "Response does not have the key 'object'"); } \ No newline at end of file From c754cffb5af061d7b4c4afd662b3d98bd3661262 Mon Sep 17 00:00:00 2001 From: Kanishka Gunawardana <83855665+KATTA-00@users.noreply.github.com> Date: Mon, 12 Aug 2024 14:09:24 +0530 Subject: [PATCH 10/36] Update docs/setup/resources/sample.jsonl Co-authored-by: Ayesh Almeida <77491511+ayeshLK@users.noreply.github.com> --- docs/setup/resources/sample.jsonl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/setup/resources/sample.jsonl b/docs/setup/resources/sample.jsonl index aadb8b9..d958a95 100644 --- a/docs/setup/resources/sample.jsonl +++ b/docs/setup/resources/sample.jsonl @@ -1,4 +1,4 @@ { "prompt": "What is the answer to 2+2", "completion": "4" -} \ No newline at end of file +} From 803c7aacc7b9cd188101b7df22bdee327849fe02 Mon Sep 17 00:00:00 2001 From: Kanishka Gunawardana <83855665+KATTA-00@users.noreply.github.com> Date: Mon, 12 Aug 2024 14:09:31 +0530 Subject: [PATCH 11/36] Update ballerina/tests/test.bal Co-authored-by: Ayesh Almeida <77491511+ayeshLK@users.noreply.github.com> --- ballerina/tests/test.bal | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ballerina/tests/test.bal b/ballerina/tests/test.bal index 2650606..1633f02 100644 --- a/ballerina/tests/test.bal +++ b/ballerina/tests/test.bal @@ -295,4 +295,4 @@ isolated function testCancelFineTuningJob(TestData testData) returns error? { // Assertions to verify response correctness. test:assertEquals(jobResponse.id, fine_tuning_job_id, "Job id mismatched"); test:assertTrue(jobResponse.hasKey("object"), "Response does not have the key 'object'"); -} \ No newline at end of file +} From e6c7012a419d7a515246bea80ffcf7a4c2fc1a1c Mon Sep 17 00:00:00 2001 From: Kanishka Gunawardana <83855665+KATTA-00@users.noreply.github.com> Date: Mon, 12 Aug 2024 14:09:38 +0530 Subject: [PATCH 12/36] Update ballerina/tests/openapi_service.bal Co-authored-by: Ayesh Almeida <77491511+ayeshLK@users.noreply.github.com> --- ballerina/tests/openapi_service.bal | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ballerina/tests/openapi_service.bal b/ballerina/tests/openapi_service.bal index 0e90ed5..92fca8b 100644 --- a/ballerina/tests/openapi_service.bal +++ b/ballerina/tests/openapi_service.bal @@ -438,4 +438,4 @@ function init() returns error? { log:printInfo("Initiating mock server"); check httpListener.attach(mockService, "/"); check httpListener.'start(); -} \ No newline at end of file +} From ee6e5fa939168a3bc8fd86a35a682370821fc679 Mon Sep 17 00:00:00 2001 From: KATTA-00 Date: Mon, 12 Aug 2024 14:22:00 +0530 Subject: [PATCH 13/36] Rename the openapi_service.bal to mock_service.bal and Add the new generated type into it --- .../{openapi_service.bal => mock_service.bal} | 14 +++++++++++++- ballerina/types.bal | 12 ------------ 2 files changed, 13 insertions(+), 13 deletions(-) rename ballerina/tests/{openapi_service.bal => mock_service.bal} (98%) diff --git a/ballerina/tests/openapi_service.bal b/ballerina/tests/mock_service.bal similarity index 98% rename from ballerina/tests/openapi_service.bal rename to ballerina/tests/mock_service.bal index 92fca8b..0dc59f6 100644 --- a/ballerina/tests/openapi_service.bal +++ b/ballerina/tests/mock_service.bal @@ -20,6 +20,18 @@ import ballerina/http; import ballerina/log; +public type OkFineTuningJob record {| + *http:Ok; + FineTuningJob body; + map headers; +|}; + +public type OkOpenAIFile record {| + *http:Ok; + OpenAIFile body; + map headers; +|}; + listener http:Listener httpListener = new (9090); http:Service mockService = service object { @@ -438,4 +450,4 @@ function init() returns error? { log:printInfo("Initiating mock server"); check httpListener.attach(mockService, "/"); check httpListener.'start(); -} +} \ No newline at end of file diff --git a/ballerina/types.bal b/ballerina/types.bal index 9212cdf..093632d 100644 --- a/ballerina/types.bal +++ b/ballerina/types.bal @@ -168,12 +168,6 @@ public type ListFineTuningJobCheckpointsResponse record { boolean has_more; }; -public type OkFineTuningJob record {| - *http:Ok; - FineTuningJob body; - map headers; -|}; - public type DeleteModelResponse record { string id; boolean deleted; @@ -306,12 +300,6 @@ public type CreateFineTuningJobRequest_integrations record { CreateFineTuningJobRequest_wandb wandb; }; -public type OkOpenAIFile record {| - *http:Ok; - OpenAIFile body; - map headers; -|}; - public type ListModelsResponse record { "list" 'object; Model[] data; From 8380d4017a7a8d4f3804331dcca6650b71dbe1c2 Mon Sep 17 00:00:00 2001 From: Kanishka Gunawardana <83855665+KATTA-00@users.noreply.github.com> Date: Mon, 12 Aug 2024 14:33:55 +0530 Subject: [PATCH 14/36] Update ballerina/tests/test.bal Co-authored-by: Ayesh Almeida <77491511+ayeshLK@users.noreply.github.com> --- ballerina/tests/test.bal | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ballerina/tests/test.bal b/ballerina/tests/test.bal index 1633f02..90fd346 100644 --- a/ballerina/tests/test.bal +++ b/ballerina/tests/test.bal @@ -27,7 +27,7 @@ configurable string apiKey = isLiveServer ? token : ""; // Initialize the connection configuration and client. final ConnectionConfig config = {auth: {token: apiKey}}; -final Client baseClient = check new Client(config, serviceUrl); +final Client openaiFinetunes = check new Client(config, serviceUrl); // Define sample file content and name. final string fileName = "sample.jsonl"; From cb37f028970537f878d2883cbe2ef2d7b8dd73d0 Mon Sep 17 00:00:00 2001 From: KATTA-00 Date: Mon, 12 Aug 2024 14:39:35 +0530 Subject: [PATCH 15/36] Update test.bal --- ballerina/tests/test.bal | 68 +++++++++------------------------------- 1 file changed, 15 insertions(+), 53 deletions(-) diff --git a/ballerina/tests/test.bal b/ballerina/tests/test.bal index 90fd346..419c85f 100644 --- a/ballerina/tests/test.bal +++ b/ballerina/tests/test.bal @@ -52,16 +52,12 @@ function dataGen() returns TestData[][] { @test:Config { dataProvider: dataGen } - isolated function testListModels(TestData testData) returns error? { - // Fetch the list of models from the API. - ListModelsResponse modelsResponse = check baseClient->/models.get(); + ListModelsResponse modelsResponse = check openaiFinetunes->/models.get(); - // Set modelId for further testing (hardcoded for demonstration). testData.modelId = "gpt-3.5-turbo"; - // Assertions to verify response correctness. test:assertEquals(modelsResponse.'object, "list", "Object type mismatched"); test:assertTrue(modelsResponse.hasKey("data"), "Response does not have the key 'data'"); } @@ -73,11 +69,9 @@ isolated function testListModels(TestData testData) returns error? { } isolated function testRetrieveModel(TestData testData) returns error? { - // Retrieve the model using the model ID. string modelId = testData.modelId; - Model modelResponse = check baseClient->/models/[modelId].get(); + Model modelResponse = check openaiFinetunes->/models/[modelId].get(); - // Assertions to verify response correctness. test:assertEquals(modelResponse.id, modelId, "Model id mismatched"); test:assertTrue(modelResponse.hasKey("object"), "Response does not have the key 'object'"); } @@ -90,11 +84,9 @@ isolated function testRetrieveModel(TestData testData) returns error? { } isolated function testDeleteModel(TestData testData) returns error? { - // Delete the model using the model ID. string modelIdCreated = testData.modelId; - DeleteModelResponse modelResponseDelete = check baseClient->/models/[modelIdCreated].delete(); + DeleteModelResponse modelResponseDelete = check openaiFinetunes->/models/[modelIdCreated].delete(); - // Assertions to verify response correctness. test:assertEquals(modelResponseDelete.id, modelIdCreated, "Model id mismatched"); test:assertTrue(modelResponseDelete.hasKey("object"), "Response does not have the key 'object'"); } @@ -104,10 +96,8 @@ isolated function testDeleteModel(TestData testData) returns error? { @test:Config {} isolated function testListFiles() returns error? { - // Fetch the list of files from the API. - ListFilesResponse filesResponse = check baseClient->/files.get(); + ListFilesResponse filesResponse = check openaiFinetunes->/files.get(); - // Assertions to verify response correctness. test:assertEquals(filesResponse.'object, "list", "Object type mismatched"); test:assertTrue(filesResponse.hasKey("data"), "Response does not have the key 'data'"); } @@ -119,19 +109,15 @@ isolated function testListFiles() returns error? { } isolated function testCreateFile(TestData testData) returns error? { - // Prepare the request to create a new file. CreateFileRequest fileRequest = { file: {fileContent, fileName}, purpose: "fine-tune" }; - // Send the request to create the file. - OpenAIFile fileResponse = check baseClient->/files.post(fileRequest); + OpenAIFile fileResponse = check openaiFinetunes->/files.post(fileRequest); - // Store the file ID for subsequent tests. testData.fileId = fileResponse.id; - // Assertions to verify response correctness. test:assertEquals(fileResponse.purpose, "fine-tune", "Purpose mismatched"); test:assertTrue(fileResponse.id !is "", "File id is empty"); } @@ -143,11 +129,9 @@ isolated function testCreateFile(TestData testData) returns error? { } isolated function testRetrieveFile(TestData testData) returns error? { - // Retrieve the file details using the file ID. string fileId = testData.fileId; - OpenAIFile fileResponse = check baseClient->/files/[fileId].get(); + OpenAIFile fileResponse = check openaiFinetunes->/files/[fileId].get(); - // Assertions to verify response correctness. test:assertEquals(fileResponse.id, fileId, "File id mismatched"); test:assertTrue(fileResponse.hasKey("object"), "Response does not have the key 'object'"); } @@ -159,11 +143,9 @@ isolated function testRetrieveFile(TestData testData) returns error? { } isolated function testDownloadFile(TestData testData) returns error? { - // Download the content of the file using the file ID. string fileId = testData.fileId; - byte[] fileContentDownload = check baseClient->/files/[fileId]/content.get(); + byte[] fileContentDownload = check openaiFinetunes->/files/[fileId]/content.get(); - // Assertions to verify response correctness. test:assertFalse(fileContentDownload.length() <= 0, "File content is empty"); } @@ -174,12 +156,10 @@ isolated function testDownloadFile(TestData testData) returns error? { dataProvider: dataGen } isolated function testDeleteFile(TestData testData) returns error? { - - // Delete the file using the file ID. + string fileId = testData.fileId; - DeleteFileResponse fileResponseDelete = check baseClient->/files/[fileId].delete(); + DeleteFileResponse fileResponseDelete = check openaiFinetunes->/files/[fileId].delete(); - // Assertions to verify response correctness. test:assertEquals(fileResponseDelete.id, fileId, "File id mismatched"); test:assertTrue(fileResponseDelete.hasKey("object"), "Response does not have the key 'object'"); } @@ -190,10 +170,8 @@ isolated function testDeleteFile(TestData testData) returns error? { @test:Config {} isolated function testListPaginatedFineTuningJobs() returns error? { - // Fetch the list of fine-tuning jobs from the API. - ListPaginatedFineTuningJobsResponse jobsResponse = check baseClient->/fine_tuning/jobs.get(); + ListPaginatedFineTuningJobsResponse jobsResponse = check openaiFinetunes->/fine_tuning/jobs.get(); - // Assertions to verify response correctness. test:assertEquals(jobsResponse.'object, "list", "Object type mismatched"); test:assertTrue(jobsResponse.hasKey("data"), "Response does not have the key 'data'"); } @@ -205,23 +183,18 @@ isolated function testListPaginatedFineTuningJobs() returns error? { } isolated function testCreateFineTuningJob(TestData testData) returns error? { - // Retrieve the file ID and model ID from the test data. string fileId = testData.fileId; string modelId = testData.modelId; - // Prepare the request to create a fine-tuning job. CreateFineTuningJobRequest fineTuneRequest = { model: modelId, training_file: fileId }; - // Send the request to create the fine-tuning job. - FineTuningJob fineTuneResponse = check baseClient->/fine_tuning/jobs.post(fineTuneRequest); + FineTuningJob fineTuneResponse = check openaiFinetunes->/fine_tuning/jobs.post(fineTuneRequest); - // Store the job ID for subsequent tests. testData.jobId = fineTuneResponse.id; - // Assertions to verify response correctness. test:assertTrue(fineTuneResponse.hasKey("object"), "Response does not have the key 'object'"); test:assertTrue(fineTuneResponse.hasKey("id"), "Response does not have the key 'id'"); } @@ -233,11 +206,9 @@ isolated function testCreateFineTuningJob(TestData testData) returns error? { } isolated function testRetrieveFineTuningJob(TestData testData) returns error? { - // Retrieve the fine-tuning job details using the job ID. string jobId = testData.jobId; - FineTuningJob jobResponse = check baseClient->/fine_tuning/jobs/[jobId].get(); + FineTuningJob jobResponse = check openaiFinetunes->/fine_tuning/jobs/[jobId].get(); - // Assertions to verify response correctness. test:assertEquals(jobResponse.id, jobId, "Job id mismatched"); test:assertEquals(jobResponse.'object, "fine_tuning.job", "Response does not have the key 'object'"); } @@ -249,13 +220,10 @@ isolated function testRetrieveFineTuningJob(TestData testData) returns error? { } isolated function testListFineTuningEvents(TestData testData) returns error? { - // Retrieve the fine-tuning job ID from the test data. string fine_tuning_job_id = testData.jobId; - // Fetch the list of events for the fine-tuning job. - ListFineTuningJobEventsResponse eventsResponse = check baseClient->/fine_tuning/jobs/[fine_tuning_job_id]/events.get(); + ListFineTuningJobEventsResponse eventsResponse = check openaiFinetunes->/fine_tuning/jobs/[fine_tuning_job_id]/events.get(); - // Assertions to verify response correctness. test:assertEquals(eventsResponse.'object, "list", "Object type mismatched"); test:assertTrue(eventsResponse.hasKey("data"), "Response does not have the key 'data'"); } @@ -267,13 +235,10 @@ isolated function testListFineTuningEvents(TestData testData) returns error? { } isolated function testListFineTuningJobCheckpoints(TestData testData) returns error? { - // Retrieve the fine-tuning job ID from the test data. string fine_tuning_job_id = testData.jobId; - // Fetch the list of checkpoints for the fine-tuning job. - ListFineTuningJobCheckpointsResponse checkpointsResponse = check baseClient->/fine_tuning/jobs/[fine_tuning_job_id]/checkpoints.get(); + ListFineTuningJobCheckpointsResponse checkpointsResponse = check openaiFinetunes->/fine_tuning/jobs/[fine_tuning_job_id]/checkpoints.get(); - // Assertions to verify response correctness. test:assertEquals(checkpointsResponse.'object, "list", "Object type mismatched"); test:assertTrue(checkpointsResponse.hasKey("data"), "Response does not have the key 'data'"); } @@ -286,13 +251,10 @@ isolated function testListFineTuningJobCheckpoints(TestData testData) returns er } isolated function testCancelFineTuningJob(TestData testData) returns error? { - // Retrieve the fine-tuning job ID from the test data. string fine_tuning_job_id = testData.jobId; - // Send the request to cancel the fine-tuning job. - FineTuningJob jobResponse = check baseClient->/fine_tuning/jobs/[fine_tuning_job_id]/cancel.post(); + FineTuningJob jobResponse = check openaiFinetunes->/fine_tuning/jobs/[fine_tuning_job_id]/cancel.post(); - // Assertions to verify response correctness. test:assertEquals(jobResponse.id, fine_tuning_job_id, "Job id mismatched"); test:assertTrue(jobResponse.hasKey("object"), "Response does not have the key 'object'"); } From a31cb1fb01cc574c01249d044bd4867fe6dddf65 Mon Sep 17 00:00:00 2001 From: Kanishka Gunawardana <83855665+KATTA-00@users.noreply.github.com> Date: Mon, 12 Aug 2024 14:56:17 +0530 Subject: [PATCH 16/36] Update ballerina/tests/mock_service.bal Co-authored-by: Ayesh Almeida <77491511+ayeshLK@users.noreply.github.com> --- ballerina/tests/mock_service.bal | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ballerina/tests/mock_service.bal b/ballerina/tests/mock_service.bal index 0dc59f6..cbc1aa3 100644 --- a/ballerina/tests/mock_service.bal +++ b/ballerina/tests/mock_service.bal @@ -450,4 +450,4 @@ function init() returns error? { log:printInfo("Initiating mock server"); check httpListener.attach(mockService, "/"); check httpListener.'start(); -} \ No newline at end of file +} From 208328dd4bcd9c2f54729f580eccfa86a63b6bc7 Mon Sep 17 00:00:00 2001 From: Kanishka Gunawardana <83855665+KATTA-00@users.noreply.github.com> Date: Mon, 12 Aug 2024 14:56:33 +0530 Subject: [PATCH 17/36] Update ballerina/tests/test.bal Co-authored-by: Ayesh Almeida <77491511+ayeshLK@users.noreply.github.com> --- ballerina/tests/test.bal | 3 --- 1 file changed, 3 deletions(-) diff --git a/ballerina/tests/test.bal b/ballerina/tests/test.bal index 419c85f..d1110cd 100644 --- a/ballerina/tests/test.bal +++ b/ballerina/tests/test.bal @@ -53,11 +53,8 @@ function dataGen() returns TestData[][] { dataProvider: dataGen } isolated function testListModels(TestData testData) returns error? { - ListModelsResponse modelsResponse = check openaiFinetunes->/models.get(); - testData.modelId = "gpt-3.5-turbo"; - test:assertEquals(modelsResponse.'object, "list", "Object type mismatched"); test:assertTrue(modelsResponse.hasKey("data"), "Response does not have the key 'data'"); } From cfa31e1de82cc112229014709bc77ced61d19202 Mon Sep 17 00:00:00 2001 From: Kanishka Gunawardana <83855665+KATTA-00@users.noreply.github.com> Date: Mon, 12 Aug 2024 14:56:42 +0530 Subject: [PATCH 18/36] Update ballerina/tests/test.bal Co-authored-by: Ayesh Almeida <77491511+ayeshLK@users.noreply.github.com> --- ballerina/tests/test.bal | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ballerina/tests/test.bal b/ballerina/tests/test.bal index d1110cd..fde1895 100644 --- a/ballerina/tests/test.bal +++ b/ballerina/tests/test.bal @@ -88,9 +88,9 @@ isolated function testDeleteModel(TestData testData) returns error? { test:assertTrue(modelResponseDelete.hasKey("object"), "Response does not have the key 'object'"); } -// Files -// Test case to list all files. -@test:Config {} +@test:Config { + groups: ["Files"] +} isolated function testListFiles() returns error? { ListFilesResponse filesResponse = check openaiFinetunes->/files.get(); From beea7464813a148afdf80843960fc8e51276c0fa Mon Sep 17 00:00:00 2001 From: KATTA-00 Date: Mon, 12 Aug 2024 15:06:27 +0530 Subject: [PATCH 19/36] Remove unwanted lines and comments --- ballerina/tests/test.bal | 46 ---------------------------------------- 1 file changed, 46 deletions(-) diff --git a/ballerina/tests/test.bal b/ballerina/tests/test.bal index fde1895..239ca11 100644 --- a/ballerina/tests/test.bal +++ b/ballerina/tests/test.bal @@ -48,7 +48,6 @@ function dataGen() returns TestData[][] { return [[testData]]; } -// Test case to list models. @test:Config { dataProvider: dataGen } @@ -59,31 +58,25 @@ isolated function testListModels(TestData testData) returns error? { test:assertTrue(modelsResponse.hasKey("data"), "Response does not have the key 'data'"); } -// Test case to retrieve a specific model by ID. @test:Config { dataProvider: dataGen, dependsOn: [testListModels] } isolated function testRetrieveModel(TestData testData) returns error? { - string modelId = testData.modelId; Model modelResponse = check openaiFinetunes->/models/[modelId].get(); - test:assertEquals(modelResponse.id, modelId, "Model id mismatched"); test:assertTrue(modelResponse.hasKey("object"), "Response does not have the key 'object'"); } -// Test case to delete a model. @test:Config { dependsOn: [testCreateFineTuningJob, testListModels, testRetrieveModel, testListFineTuningJobCheckpoints, testListFineTuningEvents], dataProvider: dataGen, enable: isLiveServer? false : true // Enable this test only for mock server. } isolated function testDeleteModel(TestData testData) returns error? { - string modelIdCreated = testData.modelId; DeleteModelResponse modelResponseDelete = check openaiFinetunes->/models/[modelIdCreated].delete(); - test:assertEquals(modelResponseDelete.id, modelIdCreated, "Model id mismatched"); test:assertTrue(modelResponseDelete.hasKey("object"), "Response does not have the key 'object'"); } @@ -92,14 +85,11 @@ isolated function testDeleteModel(TestData testData) returns error? { groups: ["Files"] } isolated function testListFiles() returns error? { - ListFilesResponse filesResponse = check openaiFinetunes->/files.get(); - test:assertEquals(filesResponse.'object, "list", "Object type mismatched"); test:assertTrue(filesResponse.hasKey("data"), "Response does not have the key 'data'"); } -// Test case to create a new file. @test:Config { dependsOn: [testListFiles], dataProvider: dataGen @@ -112,74 +102,55 @@ isolated function testCreateFile(TestData testData) returns error? { }; OpenAIFile fileResponse = check openaiFinetunes->/files.post(fileRequest); - testData.fileId = fileResponse.id; - test:assertEquals(fileResponse.purpose, "fine-tune", "Purpose mismatched"); test:assertTrue(fileResponse.id !is "", "File id is empty"); } -// Test case to retrieve details of a specific file. @test:Config { dependsOn: [testCreateFile], dataProvider: dataGen } isolated function testRetrieveFile(TestData testData) returns error? { - string fileId = testData.fileId; OpenAIFile fileResponse = check openaiFinetunes->/files/[fileId].get(); - test:assertEquals(fileResponse.id, fileId, "File id mismatched"); test:assertTrue(fileResponse.hasKey("object"), "Response does not have the key 'object'"); } -// Test case to download a file's content. @test:Config { dependsOn: [testCreateFile], dataProvider: dataGen } isolated function testDownloadFile(TestData testData) returns error? { - string fileId = testData.fileId; byte[] fileContentDownload = check openaiFinetunes->/files/[fileId]/content.get(); - test:assertFalse(fileContentDownload.length() <= 0, "File content is empty"); - } -// Test case to delete a specific file. @test:Config { dependsOn: [testCreateFile, testRetrieveFile, testDownloadFile, testCreateFineTuningJob], dataProvider: dataGen } isolated function testDeleteFile(TestData testData) returns error? { - string fileId = testData.fileId; DeleteFileResponse fileResponseDelete = check openaiFinetunes->/files/[fileId].delete(); - test:assertEquals(fileResponseDelete.id, fileId, "File id mismatched"); test:assertTrue(fileResponseDelete.hasKey("object"), "Response does not have the key 'object'"); } - -// Fine Tuning Jobs -// Test case to list all fine-tuning jobs with pagination. @test:Config {} isolated function testListPaginatedFineTuningJobs() returns error? { - ListPaginatedFineTuningJobsResponse jobsResponse = check openaiFinetunes->/fine_tuning/jobs.get(); - test:assertEquals(jobsResponse.'object, "list", "Object type mismatched"); test:assertTrue(jobsResponse.hasKey("data"), "Response does not have the key 'data'"); } -// Test case to create a new fine-tuning job. @test:Config { dependsOn: [testListModels, testCreateFile], dataProvider: dataGen } isolated function testCreateFineTuningJob(TestData testData) returns error? { - string fileId = testData.fileId; string modelId = testData.modelId; @@ -189,69 +160,52 @@ isolated function testCreateFineTuningJob(TestData testData) returns error? { }; FineTuningJob fineTuneResponse = check openaiFinetunes->/fine_tuning/jobs.post(fineTuneRequest); - testData.jobId = fineTuneResponse.id; - test:assertTrue(fineTuneResponse.hasKey("object"), "Response does not have the key 'object'"); test:assertTrue(fineTuneResponse.hasKey("id"), "Response does not have the key 'id'"); } -// Test case to retrieve details of a specific fine-tuning job. @test:Config { dependsOn: [testCreateFineTuningJob], dataProvider: dataGen } isolated function testRetrieveFineTuningJob(TestData testData) returns error? { - string jobId = testData.jobId; FineTuningJob jobResponse = check openaiFinetunes->/fine_tuning/jobs/[jobId].get(); - test:assertEquals(jobResponse.id, jobId, "Job id mismatched"); test:assertEquals(jobResponse.'object, "fine_tuning.job", "Response does not have the key 'object'"); } -// Test case to list events associated with a fine-tuning job. @test:Config { dependsOn: [testCreateFineTuningJob], dataProvider: dataGen } isolated function testListFineTuningEvents(TestData testData) returns error? { - string fine_tuning_job_id = testData.jobId; - ListFineTuningJobEventsResponse eventsResponse = check openaiFinetunes->/fine_tuning/jobs/[fine_tuning_job_id]/events.get(); - test:assertEquals(eventsResponse.'object, "list", "Object type mismatched"); test:assertTrue(eventsResponse.hasKey("data"), "Response does not have the key 'data'"); } -// Test case to list checkpoints of a fine-tuning job. @test:Config { dependsOn: [testCreateFineTuningJob], dataProvider: dataGen } isolated function testListFineTuningJobCheckpoints(TestData testData) returns error? { - string fine_tuning_job_id = testData.jobId; - ListFineTuningJobCheckpointsResponse checkpointsResponse = check openaiFinetunes->/fine_tuning/jobs/[fine_tuning_job_id]/checkpoints.get(); - test:assertEquals(checkpointsResponse.'object, "list", "Object type mismatched"); test:assertTrue(checkpointsResponse.hasKey("data"), "Response does not have the key 'data'"); } -// Test case to cancel a fine-tuning job. @test:Config { dependsOn: [testCreateFineTuningJob], dataProvider: dataGen, enable: isLiveServer? false : true // Enable this test only for mock server. } isolated function testCancelFineTuningJob(TestData testData) returns error? { - string fine_tuning_job_id = testData.jobId; - FineTuningJob jobResponse = check openaiFinetunes->/fine_tuning/jobs/[fine_tuning_job_id]/cancel.post(); - test:assertEquals(jobResponse.id, fine_tuning_job_id, "Job id mismatched"); test:assertTrue(jobResponse.hasKey("object"), "Response does not have the key 'object'"); } From 01254b52923e2d643c0050ece34340f56d8d07ad Mon Sep 17 00:00:00 2001 From: KATTA-00 Date: Mon, 12 Aug 2024 15:09:43 +0530 Subject: [PATCH 20/36] Add groups in test.bal --- ballerina/tests/test.bal | 40 +++++++++++++++++++++++++++------------- 1 file changed, 27 insertions(+), 13 deletions(-) diff --git a/ballerina/tests/test.bal b/ballerina/tests/test.bal index 239ca11..07940a2 100644 --- a/ballerina/tests/test.bal +++ b/ballerina/tests/test.bal @@ -49,7 +49,8 @@ function dataGen() returns TestData[][] { } @test:Config { - dataProvider: dataGen + dataProvider: dataGen, + groups: ["Models"] } isolated function testListModels(TestData testData) returns error? { ListModelsResponse modelsResponse = check openaiFinetunes->/models.get(); @@ -60,7 +61,8 @@ isolated function testListModels(TestData testData) returns error? { @test:Config { dataProvider: dataGen, - dependsOn: [testListModels] + dependsOn: [testListModels], + groups: ["Models"] } isolated function testRetrieveModel(TestData testData) returns error? { string modelId = testData.modelId; @@ -72,7 +74,8 @@ isolated function testRetrieveModel(TestData testData) returns error? { @test:Config { dependsOn: [testCreateFineTuningJob, testListModels, testRetrieveModel, testListFineTuningJobCheckpoints, testListFineTuningEvents], dataProvider: dataGen, - enable: isLiveServer? false : true // Enable this test only for mock server. + enable: isLiveServer? false : true, // Enable this test only for mock server. + groups: ["Models"] } isolated function testDeleteModel(TestData testData) returns error? { string modelIdCreated = testData.modelId; @@ -92,7 +95,8 @@ isolated function testListFiles() returns error? { @test:Config { dependsOn: [testListFiles], - dataProvider: dataGen + dataProvider: dataGen, + groups: ["Files"] } isolated function testCreateFile(TestData testData) returns error? { @@ -109,7 +113,8 @@ isolated function testCreateFile(TestData testData) returns error? { @test:Config { dependsOn: [testCreateFile], - dataProvider: dataGen + dataProvider: dataGen, + groups: ["Files"] } isolated function testRetrieveFile(TestData testData) returns error? { string fileId = testData.fileId; @@ -120,7 +125,8 @@ isolated function testRetrieveFile(TestData testData) returns error? { @test:Config { dependsOn: [testCreateFile], - dataProvider: dataGen + dataProvider: dataGen, + groups: ["Files"] } isolated function testDownloadFile(TestData testData) returns error? { string fileId = testData.fileId; @@ -130,7 +136,8 @@ isolated function testDownloadFile(TestData testData) returns error? { @test:Config { dependsOn: [testCreateFile, testRetrieveFile, testDownloadFile, testCreateFineTuningJob], - dataProvider: dataGen + dataProvider: dataGen, + groups: ["Files"] } isolated function testDeleteFile(TestData testData) returns error? { string fileId = testData.fileId; @@ -139,7 +146,9 @@ isolated function testDeleteFile(TestData testData) returns error? { test:assertTrue(fileResponseDelete.hasKey("object"), "Response does not have the key 'object'"); } -@test:Config {} +@test:Config { + groups: ["Fine-tuning"] +} isolated function testListPaginatedFineTuningJobs() returns error? { ListPaginatedFineTuningJobsResponse jobsResponse = check openaiFinetunes->/fine_tuning/jobs.get(); test:assertEquals(jobsResponse.'object, "list", "Object type mismatched"); @@ -148,7 +157,8 @@ isolated function testListPaginatedFineTuningJobs() returns error? { @test:Config { dependsOn: [testListModels, testCreateFile], - dataProvider: dataGen + dataProvider: dataGen, + groups: ["Fine-tuning"] } isolated function testCreateFineTuningJob(TestData testData) returns error? { string fileId = testData.fileId; @@ -167,7 +177,8 @@ isolated function testCreateFineTuningJob(TestData testData) returns error? { @test:Config { dependsOn: [testCreateFineTuningJob], - dataProvider: dataGen + dataProvider: dataGen, + groups: ["Fine-tuning"] } isolated function testRetrieveFineTuningJob(TestData testData) returns error? { string jobId = testData.jobId; @@ -178,7 +189,8 @@ isolated function testRetrieveFineTuningJob(TestData testData) returns error? { @test:Config { dependsOn: [testCreateFineTuningJob], - dataProvider: dataGen + dataProvider: dataGen, + groups: ["Fine-tuning"] } isolated function testListFineTuningEvents(TestData testData) returns error? { string fine_tuning_job_id = testData.jobId; @@ -189,7 +201,8 @@ isolated function testListFineTuningEvents(TestData testData) returns error? { @test:Config { dependsOn: [testCreateFineTuningJob], - dataProvider: dataGen + dataProvider: dataGen, + groups: ["Fine-tuning"] } isolated function testListFineTuningJobCheckpoints(TestData testData) returns error? { string fine_tuning_job_id = testData.jobId; @@ -201,7 +214,8 @@ isolated function testListFineTuningJobCheckpoints(TestData testData) returns er @test:Config { dependsOn: [testCreateFineTuningJob], dataProvider: dataGen, - enable: isLiveServer? false : true // Enable this test only for mock server. + enable: isLiveServer? false : true, // Enable this test only for mock server. + groups: ["Fine-tuning"] } isolated function testCancelFineTuningJob(TestData testData) returns error? { string fine_tuning_job_id = testData.jobId; From e2b7834a0a87ce098b5d6743bd13efe1aeec983d Mon Sep 17 00:00:00 2001 From: Kanishka Gunawardana <83855665+KATTA-00@users.noreply.github.com> Date: Mon, 12 Aug 2024 16:15:59 +0530 Subject: [PATCH 21/36] Update ballerina/tests/test.bal Co-authored-by: Ayesh Almeida <77491511+ayeshLK@users.noreply.github.com> --- ballerina/tests/test.bal | 1 - 1 file changed, 1 deletion(-) diff --git a/ballerina/tests/test.bal b/ballerina/tests/test.bal index 07940a2..14cdf51 100644 --- a/ballerina/tests/test.bal +++ b/ballerina/tests/test.bal @@ -99,7 +99,6 @@ isolated function testListFiles() returns error? { groups: ["Files"] } isolated function testCreateFile(TestData testData) returns error? { - CreateFileRequest fileRequest = { file: {fileContent, fileName}, purpose: "fine-tune" From 9a72350af7d0a7340c3f45a6ee42786249d562ee Mon Sep 17 00:00:00 2001 From: Kanishka Gunawardana <83855665+KATTA-00@users.noreply.github.com> Date: Mon, 12 Aug 2024 22:26:34 +0530 Subject: [PATCH 22/36] Update ballerina/tests/mock_service.bal Co-authored-by: Nipuna Ransinghe --- ballerina/tests/mock_service.bal | 1 - 1 file changed, 1 deletion(-) diff --git a/ballerina/tests/mock_service.bal b/ballerina/tests/mock_service.bal index cbc1aa3..ac41234 100644 --- a/ballerina/tests/mock_service.bal +++ b/ballerina/tests/mock_service.bal @@ -104,7 +104,6 @@ http:Service mockService = service object { }; return response; - } # Returns a list of files that belong to the user's organization. From e71229e180de31ef0c0d67354d5d6e2258974dfb Mon Sep 17 00:00:00 2001 From: Kanishka Gunawardana <83855665+KATTA-00@users.noreply.github.com> Date: Mon, 12 Aug 2024 22:35:53 +0530 Subject: [PATCH 23/36] Update ballerina/tests/test.bal Co-authored-by: Nipuna Ransinghe --- ballerina/tests/test.bal | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ballerina/tests/test.bal b/ballerina/tests/test.bal index 14cdf51..4c7dbda 100644 --- a/ballerina/tests/test.bal +++ b/ballerina/tests/test.bal @@ -27,7 +27,7 @@ configurable string apiKey = isLiveServer ? token : ""; // Initialize the connection configuration and client. final ConnectionConfig config = {auth: {token: apiKey}}; -final Client openaiFinetunes = check new Client(config, serviceUrl); +final Client openAIFinetunes = check new Client(config, serviceUrl); // Define sample file content and name. final string fileName = "sample.jsonl"; From 8c2b3950014b5328b6d09ddeaa6f2e5053642b3d Mon Sep 17 00:00:00 2001 From: Kanishka Gunawardana <83855665+KATTA-00@users.noreply.github.com> Date: Mon, 12 Aug 2024 22:36:10 +0530 Subject: [PATCH 24/36] Update ballerina/tests/test.bal Co-authored-by: Nipuna Ransinghe --- ballerina/tests/test.bal | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ballerina/tests/test.bal b/ballerina/tests/test.bal index 4c7dbda..034d28d 100644 --- a/ballerina/tests/test.bal +++ b/ballerina/tests/test.bal @@ -112,7 +112,7 @@ isolated function testCreateFile(TestData testData) returns error? { @test:Config { dependsOn: [testCreateFile], - dataProvider: dataGen, + dataProvider: dataGen, groups: ["Files"] } isolated function testRetrieveFile(TestData testData) returns error? { From bb1d18419b6f63e863bd2a2da0cdbe732ef00fbd Mon Sep 17 00:00:00 2001 From: KATTA-00 Date: Mon, 12 Aug 2024 22:42:43 +0530 Subject: [PATCH 25/36] Change openaiFinetunes to openAIFinetunes in test.bal --- ballerina/tests/test.bal | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/ballerina/tests/test.bal b/ballerina/tests/test.bal index 034d28d..37a91fe 100644 --- a/ballerina/tests/test.bal +++ b/ballerina/tests/test.bal @@ -53,7 +53,7 @@ function dataGen() returns TestData[][] { groups: ["Models"] } isolated function testListModels(TestData testData) returns error? { - ListModelsResponse modelsResponse = check openaiFinetunes->/models.get(); + ListModelsResponse modelsResponse = check openAIFinetunes->/models.get(); testData.modelId = "gpt-3.5-turbo"; test:assertEquals(modelsResponse.'object, "list", "Object type mismatched"); test:assertTrue(modelsResponse.hasKey("data"), "Response does not have the key 'data'"); @@ -66,7 +66,7 @@ isolated function testListModels(TestData testData) returns error? { } isolated function testRetrieveModel(TestData testData) returns error? { string modelId = testData.modelId; - Model modelResponse = check openaiFinetunes->/models/[modelId].get(); + Model modelResponse = check openAIFinetunes->/models/[modelId].get(); test:assertEquals(modelResponse.id, modelId, "Model id mismatched"); test:assertTrue(modelResponse.hasKey("object"), "Response does not have the key 'object'"); } @@ -79,7 +79,7 @@ isolated function testRetrieveModel(TestData testData) returns error? { } isolated function testDeleteModel(TestData testData) returns error? { string modelIdCreated = testData.modelId; - DeleteModelResponse modelResponseDelete = check openaiFinetunes->/models/[modelIdCreated].delete(); + DeleteModelResponse modelResponseDelete = check openAIFinetunes->/models/[modelIdCreated].delete(); test:assertEquals(modelResponseDelete.id, modelIdCreated, "Model id mismatched"); test:assertTrue(modelResponseDelete.hasKey("object"), "Response does not have the key 'object'"); } @@ -88,7 +88,7 @@ isolated function testDeleteModel(TestData testData) returns error? { groups: ["Files"] } isolated function testListFiles() returns error? { - ListFilesResponse filesResponse = check openaiFinetunes->/files.get(); + ListFilesResponse filesResponse = check openAIFinetunes->/files.get(); test:assertEquals(filesResponse.'object, "list", "Object type mismatched"); test:assertTrue(filesResponse.hasKey("data"), "Response does not have the key 'data'"); } @@ -104,7 +104,7 @@ isolated function testCreateFile(TestData testData) returns error? { purpose: "fine-tune" }; - OpenAIFile fileResponse = check openaiFinetunes->/files.post(fileRequest); + OpenAIFile fileResponse = check openAIFinetunes->/files.post(fileRequest); testData.fileId = fileResponse.id; test:assertEquals(fileResponse.purpose, "fine-tune", "Purpose mismatched"); test:assertTrue(fileResponse.id !is "", "File id is empty"); @@ -117,7 +117,7 @@ isolated function testCreateFile(TestData testData) returns error? { } isolated function testRetrieveFile(TestData testData) returns error? { string fileId = testData.fileId; - OpenAIFile fileResponse = check openaiFinetunes->/files/[fileId].get(); + OpenAIFile fileResponse = check openAIFinetunes->/files/[fileId].get(); test:assertEquals(fileResponse.id, fileId, "File id mismatched"); test:assertTrue(fileResponse.hasKey("object"), "Response does not have the key 'object'"); } @@ -129,7 +129,7 @@ isolated function testRetrieveFile(TestData testData) returns error? { } isolated function testDownloadFile(TestData testData) returns error? { string fileId = testData.fileId; - byte[] fileContentDownload = check openaiFinetunes->/files/[fileId]/content.get(); + byte[] fileContentDownload = check openAIFinetunes->/files/[fileId]/content.get(); test:assertFalse(fileContentDownload.length() <= 0, "File content is empty"); } @@ -140,7 +140,7 @@ isolated function testDownloadFile(TestData testData) returns error? { } isolated function testDeleteFile(TestData testData) returns error? { string fileId = testData.fileId; - DeleteFileResponse fileResponseDelete = check openaiFinetunes->/files/[fileId].delete(); + DeleteFileResponse fileResponseDelete = check openAIFinetunes->/files/[fileId].delete(); test:assertEquals(fileResponseDelete.id, fileId, "File id mismatched"); test:assertTrue(fileResponseDelete.hasKey("object"), "Response does not have the key 'object'"); } @@ -149,7 +149,7 @@ isolated function testDeleteFile(TestData testData) returns error? { groups: ["Fine-tuning"] } isolated function testListPaginatedFineTuningJobs() returns error? { - ListPaginatedFineTuningJobsResponse jobsResponse = check openaiFinetunes->/fine_tuning/jobs.get(); + ListPaginatedFineTuningJobsResponse jobsResponse = check openAIFinetunes->/fine_tuning/jobs.get(); test:assertEquals(jobsResponse.'object, "list", "Object type mismatched"); test:assertTrue(jobsResponse.hasKey("data"), "Response does not have the key 'data'"); } @@ -168,7 +168,7 @@ isolated function testCreateFineTuningJob(TestData testData) returns error? { training_file: fileId }; - FineTuningJob fineTuneResponse = check openaiFinetunes->/fine_tuning/jobs.post(fineTuneRequest); + FineTuningJob fineTuneResponse = check openAIFinetunes->/fine_tuning/jobs.post(fineTuneRequest); testData.jobId = fineTuneResponse.id; test:assertTrue(fineTuneResponse.hasKey("object"), "Response does not have the key 'object'"); test:assertTrue(fineTuneResponse.hasKey("id"), "Response does not have the key 'id'"); @@ -181,7 +181,7 @@ isolated function testCreateFineTuningJob(TestData testData) returns error? { } isolated function testRetrieveFineTuningJob(TestData testData) returns error? { string jobId = testData.jobId; - FineTuningJob jobResponse = check openaiFinetunes->/fine_tuning/jobs/[jobId].get(); + FineTuningJob jobResponse = check openAIFinetunes->/fine_tuning/jobs/[jobId].get(); test:assertEquals(jobResponse.id, jobId, "Job id mismatched"); test:assertEquals(jobResponse.'object, "fine_tuning.job", "Response does not have the key 'object'"); } @@ -193,7 +193,7 @@ isolated function testRetrieveFineTuningJob(TestData testData) returns error? { } isolated function testListFineTuningEvents(TestData testData) returns error? { string fine_tuning_job_id = testData.jobId; - ListFineTuningJobEventsResponse eventsResponse = check openaiFinetunes->/fine_tuning/jobs/[fine_tuning_job_id]/events.get(); + ListFineTuningJobEventsResponse eventsResponse = check openAIFinetunes->/fine_tuning/jobs/[fine_tuning_job_id]/events.get(); test:assertEquals(eventsResponse.'object, "list", "Object type mismatched"); test:assertTrue(eventsResponse.hasKey("data"), "Response does not have the key 'data'"); } @@ -205,7 +205,7 @@ isolated function testListFineTuningEvents(TestData testData) returns error? { } isolated function testListFineTuningJobCheckpoints(TestData testData) returns error? { string fine_tuning_job_id = testData.jobId; - ListFineTuningJobCheckpointsResponse checkpointsResponse = check openaiFinetunes->/fine_tuning/jobs/[fine_tuning_job_id]/checkpoints.get(); + ListFineTuningJobCheckpointsResponse checkpointsResponse = check openAIFinetunes->/fine_tuning/jobs/[fine_tuning_job_id]/checkpoints.get(); test:assertEquals(checkpointsResponse.'object, "list", "Object type mismatched"); test:assertTrue(checkpointsResponse.hasKey("data"), "Response does not have the key 'data'"); } @@ -218,7 +218,7 @@ isolated function testListFineTuningJobCheckpoints(TestData testData) returns er } isolated function testCancelFineTuningJob(TestData testData) returns error? { string fine_tuning_job_id = testData.jobId; - FineTuningJob jobResponse = check openaiFinetunes->/fine_tuning/jobs/[fine_tuning_job_id]/cancel.post(); + FineTuningJob jobResponse = check openAIFinetunes->/fine_tuning/jobs/[fine_tuning_job_id]/cancel.post(); test:assertEquals(jobResponse.id, fine_tuning_job_id, "Job id mismatched"); test:assertTrue(jobResponse.hasKey("object"), "Response does not have the key 'object'"); } From 331d585b5fe705be81d7abe913efcf07faaa1b0a Mon Sep 17 00:00:00 2001 From: KATTA-00 Date: Mon, 12 Aug 2024 22:56:26 +0530 Subject: [PATCH 26/36] Refractor the test.bal and mock_service.bal --- ballerina/tests/mock_service.bal | 55 ++++++++++++-------------------- ballerina/tests/test.bal | 26 +++++++-------- 2 files changed, 34 insertions(+), 47 deletions(-) diff --git a/ballerina/tests/mock_service.bal b/ballerina/tests/mock_service.bal index ac41234..e645f74 100644 --- a/ballerina/tests/mock_service.bal +++ b/ballerina/tests/mock_service.bal @@ -36,7 +36,6 @@ listener http:Listener httpListener = new (9090); http:Service mockService = service object { - # Delete a fine-tuned model. You must have the Owner role in your organization to delete a model. # # + model - The model to delete @@ -59,7 +58,7 @@ http:Service mockService = service object { resource function post fine_tuning/jobs/[string fine_tuning_job_id]/cancel() returns OkFineTuningJob { OkFineTuningJob response = { - body:{ + body: { "object": "fine_tuning.job", "id": fine_tuning_job_id, "model": "gpt-3.5-turbo-0125", @@ -82,11 +81,11 @@ http:Service mockService = service object { "seed": 1776549854, "estimated_finish": null, "integrations": [] - }, - headers: { - "Content-Type": "application/json" - } - }; + }, + headers: { + "Content-Type": "application/json" + } + }; return response; } @@ -139,7 +138,6 @@ http:Service mockService = service object { }; return response; - } # Returns information about a specific file. @@ -160,7 +158,6 @@ http:Service mockService = service object { }; return response; - } # Returns the contents of the specified file. @@ -172,7 +169,6 @@ http:Service mockService = service object { byte[] response = [123, 34, 116, 101, 120, 116, 34, 58, 34, 72, 101, 108, 108, 111, 44, 32, 87, 111, 114, 108, 100, 34, 125]; return response; - } # List your organization's fine-tuning jobs @@ -218,11 +214,10 @@ http:Service mockService = service object { }; return response; - } # Get info about a fine-tuning job. - # + # # [Learn more about fine-tuning](/docs/guides/fine-tuning) # # + fine_tuning_job_id - The ID of the fine-tuning job. @@ -259,7 +254,6 @@ http:Service mockService = service object { }; return response; - } # List checkpoints for a fine-tuning job. @@ -280,7 +274,7 @@ http:Service mockService = service object { "fine_tuned_model_checkpoint": "gpt-3.5-turbo-0125-1", "fine_tuning_job_id": fine_tuning_job_id, "metrics": { - "step":1 + "step": 1 }, "step_number": 2 } @@ -289,7 +283,6 @@ http:Service mockService = service object { }; return response; - } # Get status updates for a fine-tuning job. @@ -314,14 +307,13 @@ http:Service mockService = service object { }; return response; - } # Lists the currently available models, and provides basic information about each one such as the owner and availability. # # + return - OK resource function get models() returns ListModelsResponse { - + ListModelsResponse response = { 'object: "list", data: [ @@ -341,7 +333,6 @@ http:Service mockService = service object { }; return response; - } # Retrieves a model instance, providing basic information about the model such as the owner and permissioning. @@ -358,17 +349,16 @@ http:Service mockService = service object { }; return response; - } # Upload a file that can be used across various endpoints. Individual files can be up to 512 MB, and the size of all files uploaded by one organization can be up to 100 GB. - # + # # The Assistants API supports files up to 2 million tokens and of specific file types. See the [Assistants Tools guide](/docs/assistants/tools) for details. - # + # # The Fine-tuning API only supports `.jsonl` files. The input also has certain required formats for fine-tuning [chat](/docs/api-reference/fine-tuning/chat-input) or [completions](/docs/api-reference/fine-tuning/completions-input) models. - # + # # The Batch API only supports `.jsonl` files up to 100 MB in size. The input also has a specific required [format](/docs/api-reference/batch/request-input). - # + # # Please [contact us](https://help.openai.com/) if you need to increase these storage limits. # # + return - OK @@ -391,20 +381,19 @@ http:Service mockService = service object { }; return response; - } # Creates a fine-tuning job which begins the process of creating a new model from a given dataset. - # + # # Response includes details of the enqueued job including job status and the name of the fine-tuned models once complete. - # + # # [Learn more about fine-tuning](/docs/guides/fine-tuning) # # + return - OK resource function post fine_tuning/jobs(@http:Payload CreateFineTuningJobRequest payload) returns OkFineTuningJob { OkFineTuningJob response = { - body:{ + body: { "object": "fine_tuning.job", "id": "ftjob-5NikxOY1BsPHxt8Z8YBm8AX1", "model": "gpt-3.5-turbo-0125", @@ -427,16 +416,14 @@ http:Service mockService = service object { "seed": 1776549854, "estimated_finish": null, "integrations": [] - }, - headers: { - "Content-Type": "application/json" - } - }; + }, + headers: { + "Content-Type": "application/json" + } + }; return response; - } - }; function init() returns error? { diff --git a/ballerina/tests/test.bal b/ballerina/tests/test.bal index 37a91fe..96d3002 100644 --- a/ballerina/tests/test.bal +++ b/ballerina/tests/test.bal @@ -31,7 +31,7 @@ final Client openAIFinetunes = check new Client(config, serviceUrl); // Define sample file content and name. final string fileName = "sample.jsonl"; -const byte[] fileContent = [123,13,10,32,32,32,32,34,112,114,111,109,112,116,34,58,32,34,87,104,97,116,32,105,115,32,116,104,101,32,97,110,115,119,101,114,32,116,111,32,50,43,50,34,44,13,10,32,32,32,32,34,99,111,109,112,108,101,116,105,111,110,34,58,32,34,52,34,13,10,125]; +const byte[] fileContent = [123, 13, 10, 32, 32, 32, 32, 34, 112, 114, 111, 109, 112, 116, 34, 58, 32, 34, 87, 104, 97, 116, 32, 105, 115, 32, 116, 104, 101, 32, 97, 110, 115, 119, 101, 114, 32, 116, 111, 32, 50, 43, 50, 34, 44, 13, 10, 32, 32, 32, 32, 34, 99, 111, 109, 112, 108, 101, 116, 105, 111, 110, 34, 58, 32, 34, 52, 34, 13, 10, 125]; // Record type to hold test data. public type TestData record { @@ -49,7 +49,7 @@ function dataGen() returns TestData[][] { } @test:Config { - dataProvider: dataGen, + dataProvider: dataGen, groups: ["Models"] } isolated function testListModels(TestData testData) returns error? { @@ -60,7 +60,7 @@ isolated function testListModels(TestData testData) returns error? { } @test:Config { - dataProvider: dataGen, + dataProvider: dataGen, dependsOn: [testListModels], groups: ["Models"] } @@ -73,8 +73,8 @@ isolated function testRetrieveModel(TestData testData) returns error? { @test:Config { dependsOn: [testCreateFineTuningJob, testListModels, testRetrieveModel, testListFineTuningJobCheckpoints, testListFineTuningEvents], - dataProvider: dataGen, - enable: isLiveServer? false : true, // Enable this test only for mock server. + dataProvider: dataGen, + enable: isLiveServer ? false : true, // Enable this test only for mock server. groups: ["Models"] } isolated function testDeleteModel(TestData testData) returns error? { @@ -124,7 +124,7 @@ isolated function testRetrieveFile(TestData testData) returns error? { @test:Config { dependsOn: [testCreateFile], - dataProvider: dataGen, + dataProvider: dataGen, groups: ["Files"] } isolated function testDownloadFile(TestData testData) returns error? { @@ -135,7 +135,7 @@ isolated function testDownloadFile(TestData testData) returns error? { @test:Config { dependsOn: [testCreateFile, testRetrieveFile, testDownloadFile, testCreateFineTuningJob], - dataProvider: dataGen, + dataProvider: dataGen, groups: ["Files"] } isolated function testDeleteFile(TestData testData) returns error? { @@ -156,7 +156,7 @@ isolated function testListPaginatedFineTuningJobs() returns error? { @test:Config { dependsOn: [testListModels, testCreateFile], - dataProvider: dataGen, + dataProvider: dataGen, groups: ["Fine-tuning"] } isolated function testCreateFineTuningJob(TestData testData) returns error? { @@ -176,7 +176,7 @@ isolated function testCreateFineTuningJob(TestData testData) returns error? { @test:Config { dependsOn: [testCreateFineTuningJob], - dataProvider: dataGen, + dataProvider: dataGen, groups: ["Fine-tuning"] } isolated function testRetrieveFineTuningJob(TestData testData) returns error? { @@ -188,7 +188,7 @@ isolated function testRetrieveFineTuningJob(TestData testData) returns error? { @test:Config { dependsOn: [testCreateFineTuningJob], - dataProvider: dataGen, + dataProvider: dataGen, groups: ["Fine-tuning"] } isolated function testListFineTuningEvents(TestData testData) returns error? { @@ -200,7 +200,7 @@ isolated function testListFineTuningEvents(TestData testData) returns error? { @test:Config { dependsOn: [testCreateFineTuningJob], - dataProvider: dataGen, + dataProvider: dataGen, groups: ["Fine-tuning"] } isolated function testListFineTuningJobCheckpoints(TestData testData) returns error? { @@ -212,8 +212,8 @@ isolated function testListFineTuningJobCheckpoints(TestData testData) returns er @test:Config { dependsOn: [testCreateFineTuningJob], - dataProvider: dataGen, - enable: isLiveServer? false : true, // Enable this test only for mock server. + dataProvider: dataGen, + enable: isLiveServer ? false : true, // Enable this test only for mock server. groups: ["Fine-tuning"] } isolated function testCancelFineTuningJob(TestData testData) returns error? { From a1171c328d1d0ea936f8356d4cc37cb7e0fa29f4 Mon Sep 17 00:00:00 2001 From: Kanishka Gunawardana <83855665+KATTA-00@users.noreply.github.com> Date: Tue, 13 Aug 2024 10:39:09 +0530 Subject: [PATCH 27/36] Update sample.jsonl --- docs/setup/resources/sample.jsonl | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/docs/setup/resources/sample.jsonl b/docs/setup/resources/sample.jsonl index d958a95..c1a9c70 100644 --- a/docs/setup/resources/sample.jsonl +++ b/docs/setup/resources/sample.jsonl @@ -1,4 +1,10 @@ -{ - "prompt": "What is the answer to 2+2", - "completion": "4" -} +{"messages": [{"role": "user", "content": "What is the capital of France?"}, {"role": "assistant", "content": "The capital of France is Paris."}]} +{"messages": [{"role": "user", "content": "What is the primary function of the heart?"}, {"role": "assistant", "content": "The primary function of the heart is to pump blood throughout the body."}]} +{"messages": [{"role": "user", "content": "What is photosynthesis?"}, {"role": "assistant", "content": "Photosynthesis is the process by which green plants and some other organisms convert sunlight into chemical energy stored in the form of glucose."}]} +{"messages": [{"role": "user", "content": "Who wrote the play 'Romeo and Juliet'?"}, {"role": "assistant", "content": "William Shakespeare wrote the play 'Romeo and Juliet'."}]} +{"messages": [{"role": "user", "content": "Which element has the atomic number 1?"}, {"role": "assistant", "content": "Hydrogen has the atomic number 1."}]} +{"messages": [{"role": "user", "content": "What is the largest planet in our solar system?"}, {"role": "assistant", "content": "Jupiter is the largest planet in our solar system."}]} +{"messages": [{"role": "user", "content": "What is the freezing point of water in Celsius?"}, {"role": "assistant", "content": "The freezing point of water in Celsius is 0 degrees."}]} +{"messages": [{"role": "user", "content": "What is the square root of 144?"}, {"role": "assistant", "content": "The square root of 144 is 12."}]} +{"messages": [{"role": "user", "content": "Who is the author of 'To Kill a Mockingbird'?"}, {"role": "assistant", "content": "The author of 'To Kill a Mockingbird' is Harper Lee."}]} +{"messages": [{"role": "user", "content": "What is the smallest unit of life?"}, {"role": "assistant", "content": "The smallest unit of life is the cell."}]} From 5a21ba455c60b70890c870f89c427046dffad56a Mon Sep 17 00:00:00 2001 From: KATTA-00 Date: Tue, 13 Aug 2024 12:09:53 +0530 Subject: [PATCH 28/36] Update the fileContent byte array --- ballerina/tests/test.bal | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ballerina/tests/test.bal b/ballerina/tests/test.bal index 96d3002..119de63 100644 --- a/ballerina/tests/test.bal +++ b/ballerina/tests/test.bal @@ -31,7 +31,7 @@ final Client openAIFinetunes = check new Client(config, serviceUrl); // Define sample file content and name. final string fileName = "sample.jsonl"; -const byte[] fileContent = [123, 13, 10, 32, 32, 32, 32, 34, 112, 114, 111, 109, 112, 116, 34, 58, 32, 34, 87, 104, 97, 116, 32, 105, 115, 32, 116, 104, 101, 32, 97, 110, 115, 119, 101, 114, 32, 116, 111, 32, 50, 43, 50, 34, 44, 13, 10, 32, 32, 32, 32, 34, 99, 111, 109, 112, 108, 101, 116, 105, 111, 110, 34, 58, 32, 34, 52, 34, 13, 10, 125]; +const byte[] fileContent = [123, 34, 109, 101, 115, 115, 97, 103, 101, 115, 34, 58, 32, 91, 123, 34, 114, 111, 108, 101, 34, 58, 32, 34, 117, 115, 101, 114, 34, 44, 32, 34, 99, 111, 110, 116, 101, 110, 116, 34, 58, 32, 34, 87, 104, 97, 116, 32, 105, 115, 32, 116, 104, 101, 32, 99, 97, 112, 105, 116, 97, 108, 32, 111, 102, 32, 70, 114, 97, 110, 99, 101, 63, 34, 125, 44, 32, 123, 34, 114, 111, 108, 101, 34, 58, 32, 34, 97, 115, 115, 105, 115, 116, 97, 110, 116, 34, 44, 32, 34, 99, 111, 110, 116, 101, 110, 116, 34, 58, 32, 34, 84, 104, 101, 32, 99, 97, 112, 105, 116, 97, 108, 32, 111, 102, 32, 70, 114, 97, 110, 99, 101, 32, 105, 115, 32, 80, 97, 114, 105, 115, 46, 34, 125, 93, 125, 13, 10, 123, 34, 109, 101, 115, 115, 97, 103, 101, 115, 34, 58, 32, 91, 123, 34, 114, 111, 108, 101, 34, 58, 32, 34, 117, 115, 101, 114, 34, 44, 32, 34, 99, 111, 110, 116, 101, 110, 116, 34, 58, 32, 34, 87, 104, 97, 116, 32, 105, 115, 32, 116, 104, 101, 32, 112, 114, 105, 109, 97, 114, 121, 32, 102, 117, 110, 99, 116, 105, 111, 110, 32, 111, 102, 32, 116, 104, 101, 32, 104, 101, 97, 114, 116, 63, 34, 125, 44, 32, 123, 34, 114, 111, 108, 101, 34, 58, 32, 34, 97, 115, 115, 105, 115, 116, 97, 110, 116, 34, 44, 32, 34, 99, 111, 110, 116, 101, 110, 116, 34, 58, 32, 34, 84, 104, 101, 32, 112, 114, 105, 109, 97, 114, 121, 32, 102, 117, 110, 99, 116, 105, 111, 110, 32, 111, 102, 32, 116, 104, 101, 32, 104, 101, 97, 114, 116, 32, 105, 115, 32, 116, 111, 32, 112, 117, 109, 112, 32, 98, 108, 111, 111, 100, 32, 116, 104, 114, 111, 117, 103, 104, 111, 117, 116, 32, 116, 104, 101, 32, 98, 111, 100, 121, 46, 34, 125, 93, 125, 13, 10]; // Record type to hold test data. public type TestData record { From d950f7045a8e6c7e34e31f92d4585bc9d0ef6bfc Mon Sep 17 00:00:00 2001 From: KATTA-00 Date: Tue, 13 Aug 2024 12:21:00 +0530 Subject: [PATCH 29/36] Update the isLiveServer var with env variables --- ballerina/Dependencies.toml | 4 ++++ ballerina/tests/test.bal | 3 ++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ballerina/Dependencies.toml b/ballerina/Dependencies.toml index 8aad8b8..9aef484 100644 --- a/ballerina/Dependencies.toml +++ b/ballerina/Dependencies.toml @@ -257,6 +257,9 @@ dependencies = [ {org = "ballerina", name = "io"}, {org = "ballerina", name = "jballerina.java"} ] +modules = [ + {org = "ballerina", packageName = "os", moduleName = "os"} +] [[package]] org = "ballerina" @@ -320,6 +323,7 @@ dependencies = [ {org = "ballerina", name = "http"}, {org = "ballerina", name = "log"}, {org = "ballerina", name = "mime"}, + {org = "ballerina", name = "os"}, {org = "ballerina", name = "test"}, {org = "ballerina", name = "url"}, {org = "ballerinai", name = "observe"} diff --git a/ballerina/tests/test.bal b/ballerina/tests/test.bal index 119de63..a73ae18 100644 --- a/ballerina/tests/test.bal +++ b/ballerina/tests/test.bal @@ -18,9 +18,10 @@ // under the License. import ballerina/test; +import ballerina/os; // Configurable variables for environment setup. -configurable boolean isLiveServer = ?; +configurable boolean isLiveServer = os:getEnv("isLiveServer") == "true"; configurable string token = ?; configurable string serviceUrl = isLiveServer ? "https://api.openai.com/v1" : "http://localhost:9090"; configurable string apiKey = isLiveServer ? token : ""; From 50f3c829c5ce506736216fa72d73cdbe0ac45d1e Mon Sep 17 00:00:00 2001 From: Kanishka Gunawardana <83855665+KATTA-00@users.noreply.github.com> Date: Tue, 13 Aug 2024 21:32:21 +0530 Subject: [PATCH 30/36] Update ballerina/tests/test.bal Co-authored-by: Nipuna Ransinghe --- ballerina/tests/test.bal | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ballerina/tests/test.bal b/ballerina/tests/test.bal index a73ae18..ea57c6f 100644 --- a/ballerina/tests/test.bal +++ b/ballerina/tests/test.bal @@ -22,7 +22,7 @@ import ballerina/os; // Configurable variables for environment setup. configurable boolean isLiveServer = os:getEnv("isLiveServer") == "true"; -configurable string token = ?; +configurable string token = isLiveServer ? os:getEnv("OPENAI_API_KEY") : "test"; configurable string serviceUrl = isLiveServer ? "https://api.openai.com/v1" : "http://localhost:9090"; configurable string apiKey = isLiveServer ? token : ""; From 3c482744308caca83b8f25fef5efff8088fd4bbd Mon Sep 17 00:00:00 2001 From: KATTA-00 Date: Tue, 13 Aug 2024 21:35:58 +0530 Subject: [PATCH 31/36] Add "live_tests", "mock_tests" groups in test.bal --- ballerina/tests/test.bal | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/ballerina/tests/test.bal b/ballerina/tests/test.bal index ea57c6f..52c42d7 100644 --- a/ballerina/tests/test.bal +++ b/ballerina/tests/test.bal @@ -51,7 +51,7 @@ function dataGen() returns TestData[][] { @test:Config { dataProvider: dataGen, - groups: ["Models"] + groups: ["Models", "live_tests", "mock_tests"] } isolated function testListModels(TestData testData) returns error? { ListModelsResponse modelsResponse = check openAIFinetunes->/models.get(); @@ -63,7 +63,7 @@ isolated function testListModels(TestData testData) returns error? { @test:Config { dataProvider: dataGen, dependsOn: [testListModels], - groups: ["Models"] + groups: ["Models", "live_tests", "mock_tests"] } isolated function testRetrieveModel(TestData testData) returns error? { string modelId = testData.modelId; @@ -76,7 +76,7 @@ isolated function testRetrieveModel(TestData testData) returns error? { dependsOn: [testCreateFineTuningJob, testListModels, testRetrieveModel, testListFineTuningJobCheckpoints, testListFineTuningEvents], dataProvider: dataGen, enable: isLiveServer ? false : true, // Enable this test only for mock server. - groups: ["Models"] + groups: ["Models", "mock_tests"] } isolated function testDeleteModel(TestData testData) returns error? { string modelIdCreated = testData.modelId; @@ -86,7 +86,7 @@ isolated function testDeleteModel(TestData testData) returns error? { } @test:Config { - groups: ["Files"] + groups: ["Files", "live_tests", "mock_tests"] } isolated function testListFiles() returns error? { ListFilesResponse filesResponse = check openAIFinetunes->/files.get(); @@ -97,7 +97,7 @@ isolated function testListFiles() returns error? { @test:Config { dependsOn: [testListFiles], dataProvider: dataGen, - groups: ["Files"] + groups: ["Files", "live_tests", "mock_tests"] } isolated function testCreateFile(TestData testData) returns error? { CreateFileRequest fileRequest = { @@ -114,7 +114,7 @@ isolated function testCreateFile(TestData testData) returns error? { @test:Config { dependsOn: [testCreateFile], dataProvider: dataGen, - groups: ["Files"] + groups: ["Files", "live_tests", "mock_tests"] } isolated function testRetrieveFile(TestData testData) returns error? { string fileId = testData.fileId; @@ -126,7 +126,7 @@ isolated function testRetrieveFile(TestData testData) returns error? { @test:Config { dependsOn: [testCreateFile], dataProvider: dataGen, - groups: ["Files"] + groups: ["Files", "live_tests", "mock_tests"] } isolated function testDownloadFile(TestData testData) returns error? { string fileId = testData.fileId; @@ -137,7 +137,7 @@ isolated function testDownloadFile(TestData testData) returns error? { @test:Config { dependsOn: [testCreateFile, testRetrieveFile, testDownloadFile, testCreateFineTuningJob], dataProvider: dataGen, - groups: ["Files"] + groups: ["Files", "live_tests", "mock_tests"] } isolated function testDeleteFile(TestData testData) returns error? { string fileId = testData.fileId; @@ -147,7 +147,7 @@ isolated function testDeleteFile(TestData testData) returns error? { } @test:Config { - groups: ["Fine-tuning"] + groups: ["Fine-tuning", "live_tests", "mock_tests"] } isolated function testListPaginatedFineTuningJobs() returns error? { ListPaginatedFineTuningJobsResponse jobsResponse = check openAIFinetunes->/fine_tuning/jobs.get(); @@ -158,7 +158,7 @@ isolated function testListPaginatedFineTuningJobs() returns error? { @test:Config { dependsOn: [testListModels, testCreateFile], dataProvider: dataGen, - groups: ["Fine-tuning"] + groups: ["Fine-tuning", "live_tests", "mock_tests"] } isolated function testCreateFineTuningJob(TestData testData) returns error? { string fileId = testData.fileId; @@ -178,7 +178,7 @@ isolated function testCreateFineTuningJob(TestData testData) returns error? { @test:Config { dependsOn: [testCreateFineTuningJob], dataProvider: dataGen, - groups: ["Fine-tuning"] + groups: ["Fine-tuning", "live_tests", "mock_tests"] } isolated function testRetrieveFineTuningJob(TestData testData) returns error? { string jobId = testData.jobId; @@ -190,7 +190,7 @@ isolated function testRetrieveFineTuningJob(TestData testData) returns error? { @test:Config { dependsOn: [testCreateFineTuningJob], dataProvider: dataGen, - groups: ["Fine-tuning"] + groups: ["Fine-tuning", "live_tests", "mock_tests"] } isolated function testListFineTuningEvents(TestData testData) returns error? { string fine_tuning_job_id = testData.jobId; @@ -202,7 +202,7 @@ isolated function testListFineTuningEvents(TestData testData) returns error? { @test:Config { dependsOn: [testCreateFineTuningJob], dataProvider: dataGen, - groups: ["Fine-tuning"] + groups: ["Fine-tuning", "live_tests", "mock_tests"] } isolated function testListFineTuningJobCheckpoints(TestData testData) returns error? { string fine_tuning_job_id = testData.jobId; @@ -215,7 +215,7 @@ isolated function testListFineTuningJobCheckpoints(TestData testData) returns er dependsOn: [testCreateFineTuningJob], dataProvider: dataGen, enable: isLiveServer ? false : true, // Enable this test only for mock server. - groups: ["Fine-tuning"] + groups: ["Fine-tuning", "mock_tests"] } isolated function testCancelFineTuningJob(TestData testData) returns error? { string fine_tuning_job_id = testData.jobId; From d7012a3d19138c6f4259df778253076d6b5c53c2 Mon Sep 17 00:00:00 2001 From: KATTA-00 Date: Wed, 14 Aug 2024 11:53:02 +0530 Subject: [PATCH 32/36] Remove dataProvider and use module level var --- ballerina/tests/test.bal | 89 ++++++++++++---------------------------- 1 file changed, 26 insertions(+), 63 deletions(-) diff --git a/ballerina/tests/test.bal b/ballerina/tests/test.bal index 52c42d7..b925698 100644 --- a/ballerina/tests/test.bal +++ b/ballerina/tests/test.bal @@ -17,8 +17,8 @@ // specific language governing permissions and limitations // under the License. -import ballerina/test; import ballerina/os; +import ballerina/test; // Configurable variables for environment setup. configurable boolean isLiveServer = os:getEnv("isLiveServer") == "true"; @@ -33,40 +33,24 @@ final Client openAIFinetunes = check new Client(config, serviceUrl); // Define sample file content and name. final string fileName = "sample.jsonl"; const byte[] fileContent = [123, 34, 109, 101, 115, 115, 97, 103, 101, 115, 34, 58, 32, 91, 123, 34, 114, 111, 108, 101, 34, 58, 32, 34, 117, 115, 101, 114, 34, 44, 32, 34, 99, 111, 110, 116, 101, 110, 116, 34, 58, 32, 34, 87, 104, 97, 116, 32, 105, 115, 32, 116, 104, 101, 32, 99, 97, 112, 105, 116, 97, 108, 32, 111, 102, 32, 70, 114, 97, 110, 99, 101, 63, 34, 125, 44, 32, 123, 34, 114, 111, 108, 101, 34, 58, 32, 34, 97, 115, 115, 105, 115, 116, 97, 110, 116, 34, 44, 32, 34, 99, 111, 110, 116, 101, 110, 116, 34, 58, 32, 34, 84, 104, 101, 32, 99, 97, 112, 105, 116, 97, 108, 32, 111, 102, 32, 70, 114, 97, 110, 99, 101, 32, 105, 115, 32, 80, 97, 114, 105, 115, 46, 34, 125, 93, 125, 13, 10, 123, 34, 109, 101, 115, 115, 97, 103, 101, 115, 34, 58, 32, 91, 123, 34, 114, 111, 108, 101, 34, 58, 32, 34, 117, 115, 101, 114, 34, 44, 32, 34, 99, 111, 110, 116, 101, 110, 116, 34, 58, 32, 34, 87, 104, 97, 116, 32, 105, 115, 32, 116, 104, 101, 32, 112, 114, 105, 109, 97, 114, 121, 32, 102, 117, 110, 99, 116, 105, 111, 110, 32, 111, 102, 32, 116, 104, 101, 32, 104, 101, 97, 114, 116, 63, 34, 125, 44, 32, 123, 34, 114, 111, 108, 101, 34, 58, 32, 34, 97, 115, 115, 105, 115, 116, 97, 110, 116, 34, 44, 32, 34, 99, 111, 110, 116, 101, 110, 116, 34, 58, 32, 34, 84, 104, 101, 32, 112, 114, 105, 109, 97, 114, 121, 32, 102, 117, 110, 99, 116, 105, 111, 110, 32, 111, 102, 32, 116, 104, 101, 32, 104, 101, 97, 114, 116, 32, 105, 115, 32, 116, 111, 32, 112, 117, 109, 112, 32, 98, 108, 111, 111, 100, 32, 116, 104, 114, 111, 117, 103, 104, 111, 117, 116, 32, 116, 104, 101, 32, 98, 111, 100, 121, 46, 34, 125, 93, 125, 13, 10]; - -// Record type to hold test data. -public type TestData record { - string fileId; - string modelId; - string jobId; -}; - -// Initialize test data. -TestData testData = {fileId: "", modelId: "", jobId: ""}; - -// Function to generate test data. -function dataGen() returns TestData[][] { - return [[testData]]; -} +string modelId = "gpt-3.5-turbo"; +string fileId = ""; +string jobId = ""; @test:Config { - dataProvider: dataGen, groups: ["Models", "live_tests", "mock_tests"] } -isolated function testListModels(TestData testData) returns error? { +function testListModels() returns error? { ListModelsResponse modelsResponse = check openAIFinetunes->/models.get(); - testData.modelId = "gpt-3.5-turbo"; test:assertEquals(modelsResponse.'object, "list", "Object type mismatched"); test:assertTrue(modelsResponse.hasKey("data"), "Response does not have the key 'data'"); } @test:Config { - dataProvider: dataGen, dependsOn: [testListModels], groups: ["Models", "live_tests", "mock_tests"] } -isolated function testRetrieveModel(TestData testData) returns error? { - string modelId = testData.modelId; +function testRetrieveModel() returns error? { Model modelResponse = check openAIFinetunes->/models/[modelId].get(); test:assertEquals(modelResponse.id, modelId, "Model id mismatched"); test:assertTrue(modelResponse.hasKey("object"), "Response does not have the key 'object'"); @@ -74,21 +58,19 @@ isolated function testRetrieveModel(TestData testData) returns error? { @test:Config { dependsOn: [testCreateFineTuningJob, testListModels, testRetrieveModel, testListFineTuningJobCheckpoints, testListFineTuningEvents], - dataProvider: dataGen, enable: isLiveServer ? false : true, // Enable this test only for mock server. groups: ["Models", "mock_tests"] } -isolated function testDeleteModel(TestData testData) returns error? { - string modelIdCreated = testData.modelId; - DeleteModelResponse modelResponseDelete = check openAIFinetunes->/models/[modelIdCreated].delete(); - test:assertEquals(modelResponseDelete.id, modelIdCreated, "Model id mismatched"); +function testDeleteModel() returns error? { + DeleteModelResponse modelResponseDelete = check openAIFinetunes->/models/[modelId].delete(); + test:assertEquals(modelResponseDelete.id, modelId, "Model id mismatched"); test:assertTrue(modelResponseDelete.hasKey("object"), "Response does not have the key 'object'"); } @test:Config { groups: ["Files", "live_tests", "mock_tests"] } -isolated function testListFiles() returns error? { +function testListFiles() returns error? { ListFilesResponse filesResponse = check openAIFinetunes->/files.get(); test:assertEquals(filesResponse.'object, "list", "Object type mismatched"); test:assertTrue(filesResponse.hasKey("data"), "Response does not have the key 'data'"); @@ -96,28 +78,25 @@ isolated function testListFiles() returns error? { @test:Config { dependsOn: [testListFiles], - dataProvider: dataGen, groups: ["Files", "live_tests", "mock_tests"] } -isolated function testCreateFile(TestData testData) returns error? { +function testCreateFile() returns error? { CreateFileRequest fileRequest = { file: {fileContent, fileName}, purpose: "fine-tune" }; OpenAIFile fileResponse = check openAIFinetunes->/files.post(fileRequest); - testData.fileId = fileResponse.id; + fileId = fileResponse.id; test:assertEquals(fileResponse.purpose, "fine-tune", "Purpose mismatched"); test:assertTrue(fileResponse.id !is "", "File id is empty"); } @test:Config { dependsOn: [testCreateFile], - dataProvider: dataGen, groups: ["Files", "live_tests", "mock_tests"] } -isolated function testRetrieveFile(TestData testData) returns error? { - string fileId = testData.fileId; +function testRetrieveFile() returns error? { OpenAIFile fileResponse = check openAIFinetunes->/files/[fileId].get(); test:assertEquals(fileResponse.id, fileId, "File id mismatched"); test:assertTrue(fileResponse.hasKey("object"), "Response does not have the key 'object'"); @@ -125,22 +104,18 @@ isolated function testRetrieveFile(TestData testData) returns error? { @test:Config { dependsOn: [testCreateFile], - dataProvider: dataGen, groups: ["Files", "live_tests", "mock_tests"] } -isolated function testDownloadFile(TestData testData) returns error? { - string fileId = testData.fileId; +function testDownloadFile() returns error? { byte[] fileContentDownload = check openAIFinetunes->/files/[fileId]/content.get(); test:assertFalse(fileContentDownload.length() <= 0, "File content is empty"); } @test:Config { dependsOn: [testCreateFile, testRetrieveFile, testDownloadFile, testCreateFineTuningJob], - dataProvider: dataGen, groups: ["Files", "live_tests", "mock_tests"] } -isolated function testDeleteFile(TestData testData) returns error? { - string fileId = testData.fileId; +function testDeleteFile() returns error? { DeleteFileResponse fileResponseDelete = check openAIFinetunes->/files/[fileId].delete(); test:assertEquals(fileResponseDelete.id, fileId, "File id mismatched"); test:assertTrue(fileResponseDelete.hasKey("object"), "Response does not have the key 'object'"); @@ -149,7 +124,7 @@ isolated function testDeleteFile(TestData testData) returns error? { @test:Config { groups: ["Fine-tuning", "live_tests", "mock_tests"] } -isolated function testListPaginatedFineTuningJobs() returns error? { +function testListPaginatedFineTuningJobs() returns error? { ListPaginatedFineTuningJobsResponse jobsResponse = check openAIFinetunes->/fine_tuning/jobs.get(); test:assertEquals(jobsResponse.'object, "list", "Object type mismatched"); test:assertTrue(jobsResponse.hasKey("data"), "Response does not have the key 'data'"); @@ -157,31 +132,25 @@ isolated function testListPaginatedFineTuningJobs() returns error? { @test:Config { dependsOn: [testListModels, testCreateFile], - dataProvider: dataGen, groups: ["Fine-tuning", "live_tests", "mock_tests"] } -isolated function testCreateFineTuningJob(TestData testData) returns error? { - string fileId = testData.fileId; - string modelId = testData.modelId; - +function testCreateFineTuningJob() returns error? { CreateFineTuningJobRequest fineTuneRequest = { model: modelId, training_file: fileId }; FineTuningJob fineTuneResponse = check openAIFinetunes->/fine_tuning/jobs.post(fineTuneRequest); - testData.jobId = fineTuneResponse.id; + jobId = fineTuneResponse.id; test:assertTrue(fineTuneResponse.hasKey("object"), "Response does not have the key 'object'"); test:assertTrue(fineTuneResponse.hasKey("id"), "Response does not have the key 'id'"); } @test:Config { dependsOn: [testCreateFineTuningJob], - dataProvider: dataGen, groups: ["Fine-tuning", "live_tests", "mock_tests"] } -isolated function testRetrieveFineTuningJob(TestData testData) returns error? { - string jobId = testData.jobId; +function testRetrieveFineTuningJob() returns error? { FineTuningJob jobResponse = check openAIFinetunes->/fine_tuning/jobs/[jobId].get(); test:assertEquals(jobResponse.id, jobId, "Job id mismatched"); test:assertEquals(jobResponse.'object, "fine_tuning.job", "Response does not have the key 'object'"); @@ -189,37 +158,31 @@ isolated function testRetrieveFineTuningJob(TestData testData) returns error? { @test:Config { dependsOn: [testCreateFineTuningJob], - dataProvider: dataGen, groups: ["Fine-tuning", "live_tests", "mock_tests"] } -isolated function testListFineTuningEvents(TestData testData) returns error? { - string fine_tuning_job_id = testData.jobId; - ListFineTuningJobEventsResponse eventsResponse = check openAIFinetunes->/fine_tuning/jobs/[fine_tuning_job_id]/events.get(); +function testListFineTuningEvents() returns error? { + ListFineTuningJobEventsResponse eventsResponse = check openAIFinetunes->/fine_tuning/jobs/[jobId]/events.get(); test:assertEquals(eventsResponse.'object, "list", "Object type mismatched"); test:assertTrue(eventsResponse.hasKey("data"), "Response does not have the key 'data'"); } @test:Config { dependsOn: [testCreateFineTuningJob], - dataProvider: dataGen, groups: ["Fine-tuning", "live_tests", "mock_tests"] } -isolated function testListFineTuningJobCheckpoints(TestData testData) returns error? { - string fine_tuning_job_id = testData.jobId; - ListFineTuningJobCheckpointsResponse checkpointsResponse = check openAIFinetunes->/fine_tuning/jobs/[fine_tuning_job_id]/checkpoints.get(); +function testListFineTuningJobCheckpoints() returns error? { + ListFineTuningJobCheckpointsResponse checkpointsResponse = check openAIFinetunes->/fine_tuning/jobs/[jobId]/checkpoints.get(); test:assertEquals(checkpointsResponse.'object, "list", "Object type mismatched"); test:assertTrue(checkpointsResponse.hasKey("data"), "Response does not have the key 'data'"); } @test:Config { dependsOn: [testCreateFineTuningJob], - dataProvider: dataGen, enable: isLiveServer ? false : true, // Enable this test only for mock server. groups: ["Fine-tuning", "mock_tests"] } -isolated function testCancelFineTuningJob(TestData testData) returns error? { - string fine_tuning_job_id = testData.jobId; - FineTuningJob jobResponse = check openAIFinetunes->/fine_tuning/jobs/[fine_tuning_job_id]/cancel.post(); - test:assertEquals(jobResponse.id, fine_tuning_job_id, "Job id mismatched"); +function testCancelFineTuningJob() returns error? { + FineTuningJob jobResponse = check openAIFinetunes->/fine_tuning/jobs/[jobId]/cancel.post(); + test:assertEquals(jobResponse.id, jobId, "Job id mismatched"); test:assertTrue(jobResponse.hasKey("object"), "Response does not have the key 'object'"); } From 808da4e4a7ff7b213761d47483ad1ba325913c85 Mon Sep 17 00:00:00 2001 From: Kanishka Gunawardana <83855665+KATTA-00@users.noreply.github.com> Date: Wed, 14 Aug 2024 14:32:11 +0530 Subject: [PATCH 33/36] Update ballerina/tests/mock_service.bal Co-authored-by: Nipuna Ransinghe --- ballerina/tests/mock_service.bal | 3 --- 1 file changed, 3 deletions(-) diff --git a/ballerina/tests/mock_service.bal b/ballerina/tests/mock_service.bal index e645f74..47f5b7e 100644 --- a/ballerina/tests/mock_service.bal +++ b/ballerina/tests/mock_service.bal @@ -1,6 +1,3 @@ -// AUTO-GENERATED FILE. DO NOT MODIFY. -// This file is auto-generated by the Ballerina OpenAPI tool. - // Copyright (c) 2024, WSO2 LLC. (http://www.wso2.com). // // WSO2 LLC. licenses this file to you under the Apache License, From 8110079d9451f927c50ba6d434e1df0762ca9d79 Mon Sep 17 00:00:00 2001 From: Kanishka Gunawardana <83855665+KATTA-00@users.noreply.github.com> Date: Wed, 14 Aug 2024 14:32:19 +0530 Subject: [PATCH 34/36] Update ballerina/tests/test.bal Co-authored-by: Nipuna Ransinghe --- ballerina/tests/test.bal | 3 --- 1 file changed, 3 deletions(-) diff --git a/ballerina/tests/test.bal b/ballerina/tests/test.bal index b925698..f89bd91 100644 --- a/ballerina/tests/test.bal +++ b/ballerina/tests/test.bal @@ -1,6 +1,3 @@ -// AUTO-GENERATED FILE. DO NOT MODIFY. -// This file is auto-generated by the Ballerina OpenAPI tool. - // Copyright (c) 2024, WSO2 LLC. (http://www.wso2.com). // // WSO2 LLC. licenses this file to you under the Apache License, From b66a521d2cd407e421569cdb0ef6dea895f35ea0 Mon Sep 17 00:00:00 2001 From: Kanishka Gunawardana <83855665+KATTA-00@users.noreply.github.com> Date: Wed, 14 Aug 2024 14:32:30 +0530 Subject: [PATCH 35/36] Update ballerina/tests/test.bal Co-authored-by: Nipuna Ransinghe --- ballerina/tests/test.bal | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ballerina/tests/test.bal b/ballerina/tests/test.bal index f89bd91..56f469d 100644 --- a/ballerina/tests/test.bal +++ b/ballerina/tests/test.bal @@ -35,7 +35,7 @@ string fileId = ""; string jobId = ""; @test:Config { - groups: ["Models", "live_tests", "mock_tests"] + groups: ["models", "live_tests", "mock_tests"] } function testListModels() returns error? { ListModelsResponse modelsResponse = check openAIFinetunes->/models.get(); From d9f0616b3f86dd94847c450dd75923cbb4039755 Mon Sep 17 00:00:00 2001 From: KATTA-00 Date: Wed, 14 Aug 2024 14:45:28 +0530 Subject: [PATCH 36/36] Update group naming and formatting --- ballerina/Dependencies.toml | 2 +- ballerina/tests/test.bal | 37 +++++++++++++++++++------------------ 2 files changed, 20 insertions(+), 19 deletions(-) diff --git a/ballerina/Dependencies.toml b/ballerina/Dependencies.toml index 9aef484..d6606d1 100644 --- a/ballerina/Dependencies.toml +++ b/ballerina/Dependencies.toml @@ -10,7 +10,7 @@ distribution-version = "2201.9.2" [[package]] org = "ballerina" name = "auth" -version = "2.11.1" +version = "2.11.2" dependencies = [ {org = "ballerina", name = "crypto"}, {org = "ballerina", name = "jballerina.java"}, diff --git a/ballerina/tests/test.bal b/ballerina/tests/test.bal index 56f469d..14003a1 100644 --- a/ballerina/tests/test.bal +++ b/ballerina/tests/test.bal @@ -17,18 +17,19 @@ import ballerina/os; import ballerina/test; -// Configurable variables for environment setup. configurable boolean isLiveServer = os:getEnv("isLiveServer") == "true"; configurable string token = isLiveServer ? os:getEnv("OPENAI_API_KEY") : "test"; configurable string serviceUrl = isLiveServer ? "https://api.openai.com/v1" : "http://localhost:9090"; configurable string apiKey = isLiveServer ? token : ""; -// Initialize the connection configuration and client. -final ConnectionConfig config = {auth: {token: apiKey}}; +final ConnectionConfig config = { + auth: { + token: apiKey + } +}; final Client openAIFinetunes = check new Client(config, serviceUrl); -// Define sample file content and name. -final string fileName = "sample.jsonl"; +const string fileName = "sample.jsonl"; const byte[] fileContent = [123, 34, 109, 101, 115, 115, 97, 103, 101, 115, 34, 58, 32, 91, 123, 34, 114, 111, 108, 101, 34, 58, 32, 34, 117, 115, 101, 114, 34, 44, 32, 34, 99, 111, 110, 116, 101, 110, 116, 34, 58, 32, 34, 87, 104, 97, 116, 32, 105, 115, 32, 116, 104, 101, 32, 99, 97, 112, 105, 116, 97, 108, 32, 111, 102, 32, 70, 114, 97, 110, 99, 101, 63, 34, 125, 44, 32, 123, 34, 114, 111, 108, 101, 34, 58, 32, 34, 97, 115, 115, 105, 115, 116, 97, 110, 116, 34, 44, 32, 34, 99, 111, 110, 116, 101, 110, 116, 34, 58, 32, 34, 84, 104, 101, 32, 99, 97, 112, 105, 116, 97, 108, 32, 111, 102, 32, 70, 114, 97, 110, 99, 101, 32, 105, 115, 32, 80, 97, 114, 105, 115, 46, 34, 125, 93, 125, 13, 10, 123, 34, 109, 101, 115, 115, 97, 103, 101, 115, 34, 58, 32, 91, 123, 34, 114, 111, 108, 101, 34, 58, 32, 34, 117, 115, 101, 114, 34, 44, 32, 34, 99, 111, 110, 116, 101, 110, 116, 34, 58, 32, 34, 87, 104, 97, 116, 32, 105, 115, 32, 116, 104, 101, 32, 112, 114, 105, 109, 97, 114, 121, 32, 102, 117, 110, 99, 116, 105, 111, 110, 32, 111, 102, 32, 116, 104, 101, 32, 104, 101, 97, 114, 116, 63, 34, 125, 44, 32, 123, 34, 114, 111, 108, 101, 34, 58, 32, 34, 97, 115, 115, 105, 115, 116, 97, 110, 116, 34, 44, 32, 34, 99, 111, 110, 116, 101, 110, 116, 34, 58, 32, 34, 84, 104, 101, 32, 112, 114, 105, 109, 97, 114, 121, 32, 102, 117, 110, 99, 116, 105, 111, 110, 32, 111, 102, 32, 116, 104, 101, 32, 104, 101, 97, 114, 116, 32, 105, 115, 32, 116, 111, 32, 112, 117, 109, 112, 32, 98, 108, 111, 111, 100, 32, 116, 104, 114, 111, 117, 103, 104, 111, 117, 116, 32, 116, 104, 101, 32, 98, 111, 100, 121, 46, 34, 125, 93, 125, 13, 10]; string modelId = "gpt-3.5-turbo"; string fileId = ""; @@ -45,7 +46,7 @@ function testListModels() returns error? { @test:Config { dependsOn: [testListModels], - groups: ["Models", "live_tests", "mock_tests"] + groups: ["models", "live_tests", "mock_tests"] } function testRetrieveModel() returns error? { Model modelResponse = check openAIFinetunes->/models/[modelId].get(); @@ -56,7 +57,7 @@ function testRetrieveModel() returns error? { @test:Config { dependsOn: [testCreateFineTuningJob, testListModels, testRetrieveModel, testListFineTuningJobCheckpoints, testListFineTuningEvents], enable: isLiveServer ? false : true, // Enable this test only for mock server. - groups: ["Models", "mock_tests"] + groups: ["models", "mock_tests"] } function testDeleteModel() returns error? { DeleteModelResponse modelResponseDelete = check openAIFinetunes->/models/[modelId].delete(); @@ -65,7 +66,7 @@ function testDeleteModel() returns error? { } @test:Config { - groups: ["Files", "live_tests", "mock_tests"] + groups: ["files", "live_tests", "mock_tests"] } function testListFiles() returns error? { ListFilesResponse filesResponse = check openAIFinetunes->/files.get(); @@ -75,7 +76,7 @@ function testListFiles() returns error? { @test:Config { dependsOn: [testListFiles], - groups: ["Files", "live_tests", "mock_tests"] + groups: ["files", "live_tests", "mock_tests"] } function testCreateFile() returns error? { CreateFileRequest fileRequest = { @@ -91,7 +92,7 @@ function testCreateFile() returns error? { @test:Config { dependsOn: [testCreateFile], - groups: ["Files", "live_tests", "mock_tests"] + groups: ["files", "live_tests", "mock_tests"] } function testRetrieveFile() returns error? { OpenAIFile fileResponse = check openAIFinetunes->/files/[fileId].get(); @@ -101,7 +102,7 @@ function testRetrieveFile() returns error? { @test:Config { dependsOn: [testCreateFile], - groups: ["Files", "live_tests", "mock_tests"] + groups: ["files", "live_tests", "mock_tests"] } function testDownloadFile() returns error? { byte[] fileContentDownload = check openAIFinetunes->/files/[fileId]/content.get(); @@ -110,7 +111,7 @@ function testDownloadFile() returns error? { @test:Config { dependsOn: [testCreateFile, testRetrieveFile, testDownloadFile, testCreateFineTuningJob], - groups: ["Files", "live_tests", "mock_tests"] + groups: ["files", "live_tests", "mock_tests"] } function testDeleteFile() returns error? { DeleteFileResponse fileResponseDelete = check openAIFinetunes->/files/[fileId].delete(); @@ -119,7 +120,7 @@ function testDeleteFile() returns error? { } @test:Config { - groups: ["Fine-tuning", "live_tests", "mock_tests"] + groups: ["fine-tuning", "live_tests", "mock_tests"] } function testListPaginatedFineTuningJobs() returns error? { ListPaginatedFineTuningJobsResponse jobsResponse = check openAIFinetunes->/fine_tuning/jobs.get(); @@ -129,7 +130,7 @@ function testListPaginatedFineTuningJobs() returns error? { @test:Config { dependsOn: [testListModels, testCreateFile], - groups: ["Fine-tuning", "live_tests", "mock_tests"] + groups: ["fine-tuning", "live_tests", "mock_tests"] } function testCreateFineTuningJob() returns error? { CreateFineTuningJobRequest fineTuneRequest = { @@ -145,7 +146,7 @@ function testCreateFineTuningJob() returns error? { @test:Config { dependsOn: [testCreateFineTuningJob], - groups: ["Fine-tuning", "live_tests", "mock_tests"] + groups: ["fine-tuning", "live_tests", "mock_tests"] } function testRetrieveFineTuningJob() returns error? { FineTuningJob jobResponse = check openAIFinetunes->/fine_tuning/jobs/[jobId].get(); @@ -155,7 +156,7 @@ function testRetrieveFineTuningJob() returns error? { @test:Config { dependsOn: [testCreateFineTuningJob], - groups: ["Fine-tuning", "live_tests", "mock_tests"] + groups: ["fine-tuning", "live_tests", "mock_tests"] } function testListFineTuningEvents() returns error? { ListFineTuningJobEventsResponse eventsResponse = check openAIFinetunes->/fine_tuning/jobs/[jobId]/events.get(); @@ -165,7 +166,7 @@ function testListFineTuningEvents() returns error? { @test:Config { dependsOn: [testCreateFineTuningJob], - groups: ["Fine-tuning", "live_tests", "mock_tests"] + groups: ["fine-tuning", "live_tests", "mock_tests"] } function testListFineTuningJobCheckpoints() returns error? { ListFineTuningJobCheckpointsResponse checkpointsResponse = check openAIFinetunes->/fine_tuning/jobs/[jobId]/checkpoints.get(); @@ -176,7 +177,7 @@ function testListFineTuningJobCheckpoints() returns error? { @test:Config { dependsOn: [testCreateFineTuningJob], enable: isLiveServer ? false : true, // Enable this test only for mock server. - groups: ["Fine-tuning", "mock_tests"] + groups: ["fine-tuning", "mock_tests"] } function testCancelFineTuningJob() returns error? { FineTuningJob jobResponse = check openAIFinetunes->/fine_tuning/jobs/[jobId]/cancel.post();