Skip to content
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

tools.vpm: update tests, add get_installed test #20028

Merged
merged 5 commits into from
Nov 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
22 changes: 12 additions & 10 deletions cmd/tools/vpm/dependency_test.v
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
// vtest retry: 3
import os
import v.vmod
import time
import rand
import v.vmod

const v = os.quoted_path(@VEXE)
const test_path = os.join_path(os.vtmp_dir(), 'vpm_dependency_test')
const test_path = os.join_path(os.vtmp_dir(), 'vpm_dependency_test_${rand.ulid()}')

fn testsuite_begin() {
os.setenv('VMODULES', test_path, true)
Expand All @@ -29,10 +30,6 @@ fn test_install_dependencies_in_module_dir() {
os.mkdir_all(test_path) or {}
mod := 'my_module'
mod_path := os.join_path(test_path, mod)
$if windows {
// Make sure path is clean to work around CI failures with Windows MSVC.
os.system('rd /s /q ${mod_path}')
}
os.mkdir(mod_path)!
os.chdir(mod_path)!
// Create a v.mod file that lists dependencies.
Expand All @@ -51,7 +48,8 @@ fn test_install_dependencies_in_module_dir() {
}
assert v_mod.dependencies == ['markdown', 'pcre', 'https://github.com/spytheman/vtray']
// Run `v install`
mut res := os.execute_or_exit('${v} install --once')
mut res := os.execute('${v} install --once')
assert res.exit_code == 0, res.str()
assert res.output.contains('Detected v.mod file inside the project directory. Using it...'), res.output
assert res.output.contains('Installing `markdown`'), res.output
assert res.output.contains('Installing `pcre`'), res.output
Expand All @@ -60,12 +58,14 @@ fn test_install_dependencies_in_module_dir() {
assert get_mod_name(os.join_path(test_path, 'markdown', 'v.mod')) == 'markdown'
assert get_mod_name(os.join_path(test_path, 'pcre', 'v.mod')) == 'pcre'
assert get_mod_name(os.join_path(test_path, 'vtray', 'v.mod')) == 'vtray'
res = os.execute_or_exit('${v} install --once')
res = os.execute('${v} install --once')
assert res.exit_code == 0, res.str()
assert res.output.contains('All modules are already installed.'), res.output
}

fn test_resolve_external_dependencies_during_module_install() {
res := os.execute_or_exit('${v} install -v https://github.com/ttytm/emoji-mart-desktop')
res := os.execute('${v} install -v https://github.com/ttytm/emoji-mart-desktop')
assert res.exit_code == 0, res.str()
assert res.output.contains('Found 2 dependencies'), res.output
assert res.output.contains('Installing `webview`'), res.output
assert res.output.contains('Installing `miniaudio`'), res.output
Expand All @@ -77,7 +77,9 @@ fn test_resolve_external_dependencies_during_module_install() {
fn test_install_with_recursive_dependencies() {
spawn fn () {
time.sleep(2 * time.minute)
eprintln('Timeout while testing installation with recursive dependencies.')
exit(1)
}()
os.execute_or_exit('${v} install https://gitlab.com/tobealive/a')
res := os.execute('${v} install https://gitlab.com/tobealive/a')
assert res.exit_code == 0, res.str()
}
171 changes: 107 additions & 64 deletions cmd/tools/vpm/install_test.v
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
// vtest flaky: true
// vtest retry: 3
module main

import os
import rand
import v.vmod

// Running tests appends a tsession path to VTMP, which is automatically cleaned up after the test.
// The following will result in e.g. `$VTMP/tsession_7fe8e93bd740_1612958707536/test-vmodules/`.
const test_path = os.join_path(os.vtmp_dir(), 'vpm_install_test')
const test_path = os.join_path(os.vtmp_dir(), 'vpm_install_test_${rand.ulid()}')

fn testsuite_begin() {
os.setenv('VMODULES', test_path, true)
Expand All @@ -20,62 +20,62 @@ fn testsuite_end() {
os.rmdir_all(test_path) or {}
}

fn get_vmod(path string) vmod.Manifest {
return vmod.from_file(os.join_path(test_path, path, 'v.mod')) or {
eprintln('Failed to parse v.mod for `${path}`')
exit(1)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please add err: $err in the message too

}
}

fn test_install_from_vpm_ident() {
res := os.execute_or_exit('${vexe} install nedpals.args')
res := os.execute('${vexe} install nedpals.args')
assert res.exit_code == 0, res.str()
assert res.output.contains('Skipping download count increment for `nedpals.args`.'), res.output
mod := vmod.from_file(os.join_path(test_path, 'nedpals', 'args', 'v.mod')) or {
assert false, err.msg()
return
}
assert mod.name == 'nedpals.args'
assert mod.dependencies == []string{}
manifest := get_vmod(os.join_path('nedpals', 'args'))
assert manifest.name == 'nedpals.args'
assert manifest.dependencies == []string{}
}

fn test_install_from_vpm_short_ident() {
os.execute_or_exit('${vexe} install pcre')
mod := vmod.from_file(os.join_path(test_path, 'pcre', 'v.mod')) or {
assert false, err.msg()
return
}
assert mod.name == 'pcre'
assert mod.description == 'A simple regex library for V.'
res := os.execute('${vexe} install pcre')
assert res.exit_code == 0, res.str()
manifest := get_vmod('pcre')
assert manifest.name == 'pcre'
assert manifest.description == 'A simple regex library for V.'
}

fn test_install_from_git_url() {
mut res := os.execute_or_exit('${vexe} install https://github.com/vlang/markdown')
mut res := os.execute('${vexe} install https://github.com/vlang/markdown')
assert res.exit_code == 0, res.str()
assert res.output.contains('Installing `markdown`'), res.output
mut mod := vmod.from_file(os.join_path(test_path, 'markdown', 'v.mod')) or {
assert false, err.msg()
return
}
assert mod.name == 'markdown'
assert mod.dependencies == []string{}
res = os.execute_or_exit('${vexe} install http://github.com/Wertzui123/HashMap')
mut manifest := get_vmod('markdown')
assert manifest.name == 'markdown'
assert manifest.dependencies == []string{}
res = os.execute('${vexe} install http://github.com/Wertzui123/HashMap')
assert res.exit_code == 0, res.str()
assert res.output.contains('Installing `HashMap`'), res.output
assert res.output.contains('`http` is deprecated'), res.output
mod = vmod.from_file(os.join_path(test_path, 'wertzui123', 'hashmap', 'v.mod')) or {
assert false, err.msg()
return
}
res = os.execute_or_exit('${vexe} install http://github.com/Wertzui123/HashMap')
manifest = get_vmod(os.join_path('wertzui123', 'hashmap'))
res = os.execute('${vexe} install http://github.com/Wertzui123/HashMap')
assert res.exit_code == 0, res.str()
assert res.output.contains('Updating module `wertzui123.hashmap`'), res.output
assert res.output.contains('`http` is deprecated'), res.output
res = os.execute_or_exit('${vexe} install https://gitlab.com/tobealive/webview')
res = os.execute('${vexe} install https://gitlab.com/tobealive/webview')
assert res.exit_code == 0, res.str()
assert res.output.contains('Installed `webview`'), res.output
}

fn test_install_already_existent() {
mut res := os.execute_or_exit('${vexe} install https://github.com/vlang/markdown')
assert res.output.contains('Updating module `markdown` in `${test_path}/markdown`'), res.output
mod := vmod.from_file(os.join_path(test_path, 'markdown', 'v.mod')) or {
assert false, err.msg()
return
}
assert mod.name == 'markdown'
assert mod.dependencies == []string{}
mut res := os.execute('${vexe} install https://github.com/vlang/markdown')
assert res.exit_code == 0, res.str()
assert res.output.contains('Updating module `markdown`'), res.output
manifest := get_vmod('markdown')
assert manifest.name == 'markdown'
assert manifest.dependencies == []string{}
// The same module but with the `.git` extension added.
os.execute_or_exit('${vexe} install https://github.com/vlang/markdown.git')
assert res.output.contains('Updating module `markdown` in `${test_path}/markdown`'), res.output
res = os.execute('${vexe} install https://github.com/vlang/markdown.git')
assert res.exit_code == 0, res.str()
assert res.output.contains('Updating module `markdown`'), res.output
}

fn test_install_once() {
Expand All @@ -89,26 +89,26 @@ fn test_install_once() {
os.mkdir_all(test_path) or {}

// Install markdown module.
os.execute_or_exit('${vexe} install markdown')
mut res := os.execute('${vexe} install markdown')
assert res.exit_code == 0, res.str()
// Keep track of the last modified state of the v.mod file of the installed markdown module.
md_last_modified := os.file_last_mod_unix(os.join_path(test_path, 'markdown', 'v.mod'))

install_cmd := '${@VEXE} install https://github.com/vlang/markdown https://github.com/vlang/pcre --once -v'
// Try installing two modules, one of which is already installed.
mut res := os.execute_or_exit(install_cmd)
res = os.execute(install_cmd)
assert res.exit_code == 0, res.str()
assert res.output.contains("Already installed modules: ['markdown']"), res.output
mod := vmod.from_file(os.join_path(test_path, 'pcre', 'v.mod')) or {
assert false, err.msg()
return
}
assert mod.name == 'pcre'
assert mod.description == 'A simple regex library for V.'
manifest := get_vmod('pcre')
assert manifest.name == 'pcre'
assert manifest.description == 'A simple regex library for V.'
// Ensure the before installed markdown module wasn't modified.
assert md_last_modified == os.file_last_mod_unix(os.join_path(test_path, 'markdown',
'v.mod'))

// Try installing two modules that are both already installed.
res = os.execute_or_exit(install_cmd)
res = os.execute(install_cmd)
assert res.exit_code == 0, res.str()
assert res.output.contains('All modules are already installed.'), res.output
assert md_last_modified == os.file_last_mod_unix(os.join_path(test_path, 'markdown',
'v.mod'))
Expand All @@ -123,19 +123,19 @@ fn test_missing_repo_name_in_url() {

fn test_manifest_detection() {
// head branch == `main`.
mut mod := fetch_manifest('v-analyzer', 'https://github.com/v-analyzer/v-analyzer',
mut manifest := fetch_manifest('v-analyzer', 'https://github.com/v-analyzer/v-analyzer',
'', true) or {
assert false
return
}
assert mod.name == 'v-analyzer'
assert mod.dependencies == ['https://github.com/v-analyzer/v-tree-sitter']
assert manifest.name == 'v-analyzer'
assert manifest.dependencies == ['https://github.com/v-analyzer/v-tree-sitter']
// head branch == `master`.
mod = fetch_manifest('ui', 'https://github.com/pisaiah/ui', '', true) or {
manifest = fetch_manifest('ui', 'https://github.com/pisaiah/ui', '', true) or {
assert false
return
}
assert mod.name == 'iui'
assert manifest.name == 'iui'
// not a V module.
if v := fetch_manifest('octocat', 'https://github.com/octocat/octocat.github.io',
'', true)
Expand All @@ -147,24 +147,67 @@ fn test_manifest_detection() {
assert res.exit_code == 1
assert res.output.contains('failed to find `v.mod` for `https://github.com/octocat/octocat.github.io`'), res.output
// No error for vpm modules yet.
res = os.execute_or_exit('${vexe} install spytheman.regex')
res = os.execute('${vexe} install spytheman.regex')
assert res.exit_code == 0, res.str()
assert res.output.contains('`spytheman.regex` is missing a manifest file'), res.output
assert res.output.contains('Installing `spytheman.regex`'), res.output
}

fn test_install_potentially_conflicting() {
mut res := os.execute('${vexe} install ui')
assert res.output.contains('Installed `ui`')
mut mod := vmod.from_file(os.join_path(test_path, 'ui', 'v.mod')) or {
assert false, err.msg()
return
}
assert mod.name == 'ui'
mut manifest := get_vmod('ui')
assert manifest.name == 'ui'
res = os.execute('${vexe} install https://github.com/isaiahpatton/ui')
assert res.output.contains('Installed `iui`')
mod = vmod.from_file(os.join_path(test_path, 'iui', 'v.mod')) or {
assert false, err.msg()
return
manifest = get_vmod('iui')
assert manifest.name == 'iui'
}

fn test_get_installed_version() {
test_project_path := os.join_path(test_path, 'test_project')
os.mkdir_all(test_project_path)!
os.chdir(test_project_path)!
os.write_file('v.mod', '')!
if os.getenv('CI') != '' {
os.execute_or_exit('git config --global user.email "v@vi.com"')
os.execute_or_exit('git config --global user.name "V CI"')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

vi.com ?

}
mut res := os.execute('git init')
assert res.exit_code == 0, res.str()
res = os.execute('git add .')
assert res.exit_code == 0, res.str()
res = os.execute('git commit -m "initial commit"')
assert res.exit_code == 0, res.str()
mut mod := Module{
install_path: test_project_path
}
assert mod.name == 'iui'
mod.get_installed()
assert mod.is_installed
assert mod.installed_version == ''

// Create a tag -> latests commit and tag are at the same state,
// but it should not be treated as a version installation, when there is another head branch.
res = os.execute('git tag v0.1.0')
assert res.exit_code == 0, res.str()
mod.is_installed = false
mod.get_installed()
assert mod.is_installed
assert mod.installed_version == ''

os.execute('git checkout v0.1.0')
assert res.exit_code == 0, res.str()
mod.is_installed = false
mod.get_installed()
assert mod.is_installed
assert mod.installed_version == ''

os.execute('git branch -D master')
assert res.exit_code == 0, res.str()
os.execute('git reset --hard v0.1.0')
assert res.exit_code == 0, res.str()
mod.is_installed = false
mod.get_installed()
assert mod.is_installed
assert mod.installed_version == 'v0.1.0'
}
39 changes: 21 additions & 18 deletions cmd/tools/vpm/install_version_input_test.v
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
// vtest retry: 3
import os
import rand
import v.vmod

const vexe = os.quoted_path(@VEXE)
const test_path = os.join_path(os.vtmp_dir(), 'vpm_install_version_input_test')
const test_path = os.join_path(os.vtmp_dir(), 'vpm_install_version_input_test_${rand.ulid()}')
const expect_tests_path = os.join_path(@VEXEROOT, 'cmd', 'tools', 'vpm', 'expect')
const expect_exe = os.quoted_path(os.find_abs_path_of_executable('expect') or {
eprintln('skipping test, since expect is missing')
Expand All @@ -24,40 +25,42 @@ fn testsuite_end() {
os.rmdir_all(test_path) or {}
}

fn get_mod_name_and_version(path string) (string, string) {
mod := vmod.from_file(os.join_path(test_path, path, 'v.mod')) or {
eprintln(err)
return '', ''
fn get_vmod(path string) vmod.Manifest {
return vmod.from_file(os.join_path(test_path, path, 'v.mod')) or {
eprintln('Failed to parse v.mod for `${path}`')
exit(1)
}
return mod.name, mod.version
}

// Test installing another version of a module of which an explicit version is already installed.
fn test_reinstall_mod_with_version_installation() {
// Install version.
mod := 'vsl'
ident := 'vsl'
tag := 'v0.1.47'
os.execute_or_exit('${vexe} install ${mod}@${tag}')
mut name, mut version := get_mod_name_and_version(mod)
assert name == mod
assert version == tag.trim_left('v')
mut res := os.execute('${vexe} install ${ident}@${tag}')
assert res.exit_code == 0, res.str()
mut manifest := get_vmod(ident)
assert manifest.name == ident
assert manifest.version == tag.trim_left('v')

// Try reinstalling.
new_tag := 'v0.1.50'
install_path := os.real_path(os.join_path(test_path, mod))
expect_args := [vexe, mod, tag, new_tag, install_path].join(' ')
install_path := os.real_path(os.join_path(test_path, ident))
expect_args := [vexe, ident, tag, new_tag, install_path].join(' ')

// Decline.
decline_test := os.join_path(expect_tests_path, 'decline_reinstall_mod_with_version_installation.expect')
manifest_path := os.join_path(install_path, 'v.mod')
last_modified := os.file_last_mod_unix(manifest_path)
os.execute_or_exit('${expect_exe} ${decline_test} ${expect_args}')
res = os.execute('${expect_exe} ${decline_test} ${expect_args}')
assert res.exit_code == 0, res.str()
assert last_modified == os.file_last_mod_unix(manifest_path)

// Accept.
accept_test := os.join_path(expect_tests_path, 'accept_reinstall_mod_with_version_installation.expect')
os.execute_or_exit('${expect_exe} ${accept_test} ${expect_args}')
name, version = get_mod_name_and_version(mod)
assert name == mod, name
assert version == new_tag.trim_left('v'), version
res = os.execute('${expect_exe} ${accept_test} ${expect_args}')
assert res.exit_code == 0, res.str()
manifest = get_vmod(ident)
assert manifest.name == ident
assert manifest.version == new_tag.trim_left('v')
}