-
Notifications
You must be signed in to change notification settings - Fork 355
Tests for non-priviledged commands #283
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
rugvedS07
wants to merge
69
commits into
main
Choose a base branch
from
rugved/tests
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
69 commits
Select commit
Hold shift + click to select a range
453ad1f
Tests for non-priviledged commands
rugvedS07 35ba999
Basic workflow for testing lms
rugvedS07 fe8fd6b
Correct repo name
rugvedS07 6cf6377
Correct branch variable name
rugvedS07 050e5b8
Fetch branch
rugvedS07 612cfdc
Submodules true
rugvedS07 79b84ee
Proper dependency resolution
rugvedS07 ec8586a
Correct action path
rugvedS07 6c8de46
Another path attempt
rugvedS07 fef3a19
Better runner
rugvedS07 ea6ecad
Revert the runner and disable server stop tests
rugvedS07 772fbe5
Add testing for lms cli from lmstudiojs
rugvedS07 6a89423
Other grep command
rugvedS07 06978b4
Avoid shell execution
rugvedS07 8d52b32
Use heredoc
rugvedS07 bb58787
Cleaner solution with tee
rugvedS07 940b6fa
ENV variable solution
rugvedS07 b598e17
Better checkout logic
rugvedS07 2769c3b
tmate session
rugvedS07 e22b147
Specify port
rugvedS07 345b634
Change all the tests to use localhost and port 1234
rugvedS07 c566906
Change how runCommandSync works
rugvedS07 73eb4b2
Better chat tests
rugvedS07 7625e5e
Remove the tests which canont be run in a docker context
rugvedS07 2da91f1
Espace for quotes
rugvedS07 27970b1
Remove flags test
rugvedS07 aa3d44c
Rename all tests to be heavy
rugvedS07 a00b81f
CLI_PATH and remove help tests
rugvedS07 88f85f7
Revert package.json
rugvedS07 10c4dab
Fix unload error
rugvedS07 e7ea3b7
Make changes to tests
rugvedS07 6f782ab
Better list tests
rugvedS07 b08e7f6
Better load tests
rugvedS07 1bf5a66
Better status tests
rugvedS07 9c9b931
Better unload tests
rugvedS07 3ef6dd6
Better import tests
rugvedS07 6816aae
Skip chat tests for now
rugvedS07 6558999
Add comment
rugvedS07 7671c28
Ready file logic and CI changes
rugvedS07 7f1ac39
Add git to the container
rugvedS07 3e76aad
Remove docker
rugvedS07 10c57e8
add google/
rugvedS07 15ae229
Download model from cloudflare
rugvedS07 3a6eeba
Add -p to the other mkdir
rugvedS07 41b0587
Address comments
rugvedS07 a88255c
Remove hardcoded version
rugvedS07 b4bf902
Remove all --host --port
rugvedS07 9d8db72
Skip chat tests for now
rugvedS07 f63ba5b
Skip import test
rugvedS07 a493199
Use LMS FORCE PROD
rugvedS07 4d34d0f
Verbose tests for cli
rugvedS07 310c5da
Fix tests
rugvedS07 15aaf51
Add debug steps
rugvedS07 6ab503b
add another lms-clone for test
rugvedS07 e285a2c
Remove tmate and wget in different location
rugvedS07 b1279b2
Add --quiet and status
rugvedS07 e84a829
More lms status
rugvedS07 429da9a
Fix error in workflow
rugvedS07 03b478e
Add tmate again and remove all lms status
rugvedS07 fa5b715
Single step attempt
rugvedS07 2462d3b
wget correction
rugvedS07 1dcfd0a
Correct path
rugvedS07 b284e81
Remove force prod
rugvedS07 803fb6c
Temp use lms get
rugvedS07 7301385
Renable actual import tests
rugvedS07 c68f6fb
Create a valid gguf file
rugvedS07 9b9a36a
Use a test folder instead
rugvedS07 bb2e35d
Add separator logic
rugvedS07 4a2d982
Fix awk command
rugvedS07 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,118 @@ | ||
| name: LMS CLI Tests | ||
|
|
||
| # Group workflow runs by branch and cancel in-progress runs on new commits to avoid PR wastefulness | ||
| concurrency: | ||
| group: ${{ github.workflow }}-${{ github.ref }} | ||
| cancel-in-progress: true | ||
|
|
||
| on: | ||
| workflow_dispatch: | ||
| pull_request: | ||
| types: [opened, synchronize, reopened, labeled] | ||
|
|
||
| jobs: | ||
| build-and-test: | ||
| name: Build and Test LMS CLI | ||
| runs-on: ubuntu-latest | ||
| container: | ||
| image: lmstudio/llmster-preview:cpu | ||
| timeout-minutes: 30 | ||
| steps: | ||
| - name: Install git on container | ||
| run: | | ||
| apt update | ||
| apt install -y git | ||
| - name: Determine lmstudio.js branch | ||
| id: branch | ||
| env: | ||
| PR_BODY: ${{ github.event.pull_request.body }} | ||
| run: | | ||
| echo "$PR_BODY" > pr_body.txt | ||
|
|
||
| # Always look below separators first | ||
| LMS_JS_BRANCH=$(awk '/^-+$/{flag=1; next} flag && /lmstudio-js-branch:/{gsub(/.*lmstudio-js-branch:[ \t]*/, ""); gsub(/[ \t].*/, ""); print; exit}' pr_body.txt || true) | ||
|
|
||
| # If not found in separator sections, try anywhere in PR body | ||
| if [ -z "$LMS_JS_BRANCH" ]; then | ||
| LMS_JS_BRANCH=$(grep -oP 'lmstudio-js-branch:\s*\K\S+' pr_body.txt || true) | ||
| fi | ||
|
|
||
| # Fallback to main if not found | ||
| if [ -z "$LMS_JS_BRANCH" ]; then | ||
| LMS_JS_BRANCH="main" | ||
| fi | ||
|
|
||
| echo "branch=$LMS_JS_BRANCH" >> $GITHUB_OUTPUT | ||
|
|
||
| - name: Checkout lmstudio.js repo | ||
| uses: actions/checkout@v4 | ||
| with: | ||
| repository: lmstudio-ai/lmstudio-js | ||
| ref: ${{ steps.branch.outputs.branch }} | ||
| path: lmstudio.js | ||
| submodules: true | ||
| - name: Fetch and checkout lms-cli branch | ||
| run: | | ||
| cd lmstudio.js/packages/lms-cli | ||
| git fetch origin ${{ github.head_ref }}:${{ github.head_ref }} | ||
| git checkout ${{ github.head_ref }} | ||
|
|
||
| - name: Setup Node.js | ||
| uses: actions/setup-node@v4 | ||
| with: | ||
| node-version: "20" | ||
| cache: "npm" | ||
| cache-dependency-path: lmstudio.js/package-lock.json | ||
|
|
||
| - name: Install dependencies | ||
| run: | | ||
| cd lmstudio.js | ||
| npm install | ||
|
|
||
| - name: Build lmstudio.js | ||
| run: | | ||
| cd lmstudio.js | ||
| npm run build | ||
|
|
||
| - name: Run daemon and tests | ||
| id: run | ||
| run: | | ||
| cd /app | ||
| echo "Starting up llmd..." | ||
| ./daemon-run.sh & | ||
| DAEMON_PID=$! | ||
| LM_HOME="${HOME}/.lmstudio" | ||
| MAX_WAIT=120 | ||
| START_TIME=$(date +%s) | ||
| # Check for the ready files | ||
| while true; do | ||
| # Check for any .ready file | ||
| if ls "${LM_HOME}"/.ready* 1> /dev/null 2>&1; then | ||
| break | ||
| fi | ||
| CURRENT_TIME=$(date +%s) | ||
| ELAPSED=$((CURRENT_TIME - START_TIME)) | ||
| if [ $ELAPSED -ge $MAX_WAIT ]; then | ||
| echo "Timed out waiting for llmster to start after ${MAX_WAIT} seconds." | ||
| break | ||
| fi | ||
| sleep 1 | ||
| done | ||
|
|
||
| # Setup model | ||
| # mkdir -p /.lmstudio/hub/models/google | ||
| # cd /.lmstudio/hub/models/google | ||
| # lms clone google/gemma-3-1b | ||
| # mkdir -p /.lmstudio/models/lmstudio-community/gemma-3-1b-it-GGUF | ||
| # cd /.lmstudio/models/lmstudio-community/gemma-3-1b-it-GGUF | ||
| # if ! command -v wget &> /dev/null; then | ||
| # apt-get update | ||
| # apt-get install -y wget | ||
| # fi | ||
| # wget --quiet -P /tmp https://models.lmstudio.ai/models/gemma-3-1b-it-Q4_K_M.gguf && mv /tmp/gemma-3-1b-it-Q4_K_M.gguf gemma-3-1b-it-Q4_K_M.gguf | ||
|
|
||
| lms get google/gemma-3-1b -y | ||
|
|
||
| # Run tests | ||
| cd $GITHUB_WORKSPACE/lmstudio.js | ||
| npm run test-cli -- --verbose | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,106 @@ | ||
| import path from "path"; | ||
| import { TEST_CLI_PATH, testRunCommandSync } from "../test-utils.js"; | ||
|
|
||
| // We skip chat tests to because we don't have max_tokens here. | ||
| describe.skip("chat heavy", () => { | ||
| const cliPath = path.join(__dirname, TEST_CLI_PATH); | ||
| const modelIdentifier = "test-model"; | ||
| const modelToUse = "gemma-3-1b"; | ||
|
|
||
| beforeAll(async () => { | ||
| // Ensure the test model is loaded | ||
| const { status } = testRunCommandSync("node", [ | ||
| cliPath, | ||
| "load", | ||
| modelToUse, | ||
| "--identifier", | ||
| modelIdentifier, | ||
| "--yes", | ||
| ]); | ||
| if (status !== 0) { | ||
| throw new Error(`Failed to load test model: ${modelIdentifier}`); | ||
| } | ||
| }, 30000); | ||
|
|
||
| afterAll(async () => { | ||
| // Clean up by unloading the model | ||
| const { status } = testRunCommandSync("node", [cliPath, "unload", modelIdentifier]); | ||
| if (status !== 0) { | ||
| console.warn(`Failed to unload test model: ${modelIdentifier}`); | ||
| } | ||
| }, 10000); | ||
|
|
||
| it("should respond to simple prompt with specific model", () => { | ||
| const { status, stdout, stderr } = testRunCommandSync("node", [ | ||
| cliPath, | ||
| "chat", | ||
| modelIdentifier, | ||
| "--prompt", | ||
| '"What is 2+2? Answer briefly:"', | ||
| ]); | ||
|
|
||
| if (status !== 0) console.error("Chat stderr:", stderr); | ||
| expect(status).toBe(0); | ||
| expect(stdout.toLowerCase()).toContain("4"); | ||
| }, 15000); | ||
|
|
||
| it("should use custom system prompt", () => { | ||
| const { status, stdout, stderr } = testRunCommandSync("node", [ | ||
| cliPath, | ||
| "chat", | ||
| modelIdentifier, | ||
| "--prompt", | ||
| '"What is your role?"', | ||
| "--system-prompt", | ||
| '"You are a helpful assistant."', | ||
| ]); | ||
|
|
||
| if (status !== 0) console.error("Chat stderr:", stderr); | ||
| expect(status).toBe(0); | ||
| expect(stdout.toLowerCase()).toMatch(/(assistant|help)/); | ||
| }, 15000); | ||
|
|
||
| it("should display stats when --stats flag is used", () => { | ||
| const { status, stderr } = testRunCommandSync("node", [ | ||
| cliPath, | ||
| "chat", | ||
| modelIdentifier, | ||
| "--prompt", | ||
| '"Hi"', | ||
| "--stats", | ||
| ]); | ||
|
|
||
| if (status !== 0) console.error("Chat stderr:", stderr); | ||
| expect(status).toBe(0); | ||
| expect(stderr).toContain("Prediction Stats:"); | ||
| expect(stderr).toContain("Stop Reason:"); | ||
| expect(stderr).toContain("Tokens/Second:"); | ||
| }, 15000); | ||
|
|
||
| it("should work with default model when no model specified", () => { | ||
| const { status, stdout, stderr } = testRunCommandSync("node", [ | ||
| cliPath, | ||
| "chat", | ||
| "--prompt", | ||
| "\"Say hello. Respond with just 'hello'\"", | ||
| ]); | ||
|
|
||
| if (status !== 0) console.error("Chat stderr:", stderr); | ||
| expect(status).toBe(0); | ||
| expect(stdout.toLowerCase()).toContain("hello"); | ||
| }, 15000); | ||
|
|
||
| it("should fail gracefully with non-existent model", () => { | ||
| const { status, stderr } = testRunCommandSync("node", [ | ||
| cliPath, | ||
| "chat", | ||
| "non-existent-model", | ||
| "--prompt", | ||
| '"test"', | ||
| ]); | ||
|
|
||
| expect(status).not.toBe(0); | ||
| expect(stderr).toContain("not found"); | ||
| expect(stderr).toContain("lms ls"); | ||
| }); | ||
| }); |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this be removed?