@@ -2,9 +2,8 @@ import os
22import log
33import net.http
44import time
5- import json
5+ import x.json2 as json
66import api
7- import term
87
98const gitly_url = 'http://127.0.0.1:8080'
109
@@ -16,8 +15,14 @@ const test_github_repo_url = 'https://github.com/vlang/pcre'
1615
1716const test_github_repo_primary_branch = 'master'
1817
18+ // When GITLY_TEST_SKIP_REMOTE_REPO is set, the tests that clone a remote GitHub
19+ // repository (and therefore need network access + a working outbound git/https
20+ // stack) are skipped. This keeps the pure "gitly serves the expected HTML"
21+ // checks usable as a fast, reliable smoke test (e.g. in vlang/v's Windows CI).
22+ const skip_remote_repo = os.getenv ('GITLY_TEST_SKIP_REMOTE_REPO' ) != ''
23+
1924fn main () {
20- before ()!
25+ mut gitly_process := before ()!
2126
2227 test_index_page ()
2328
@@ -43,36 +48,42 @@ fn main() {
4348 assert get_repo_issue_count (token, test_username, 'test1' ) == 0
4449 assert get_repo_branch_count (token, test_username, 'test1' ) == 0
4550
46- repo_name := 'test2'
47- test_create_repo (token, repo_name, test_github_repo_url)
48- // wait while repo is cloning
49- time.sleep (5 * time.second)
50- // get repo
51- assert get_repo_commit_count (token, test_username, repo_name, test_github_repo_primary_branch) > 0
52- assert get_repo_issue_count (token, test_username, repo_name) == 0
53- assert get_repo_branch_count (token, test_username, repo_name) > 0
54- test_repo_page (test_username, repo_name)
55- test_branch_page (test_username, repo_name, test_github_repo_primary_branch)
56- test_repos_page (test_username)
57- test_repo_settings_page (test_username, repo_name)
58- test_contributors_page (test_username, repo_name)
59- // test_issues_page(test_username)
60- test_stars_page (test_username)
61- test_settings_page (test_username)
62- test_commits_page (test_username, repo_name, test_github_repo_primary_branch)
63- test_branches_page (test_username, repo_name)
64- test_repo_tree (test_username, repo_name, test_github_repo_primary_branch, 'c' )
65- // this makes sure that the blob (and the tree?) is ready
66- test_repo_tree (test_username, repo_name, test_github_repo_primary_branch, 'examples' )
67- test_blob_page (test_username, repo_name, test_github_repo_primary_branch, 'examples/hello.v' )
68- // test_refs_page(test_username, repo_name)
69- // test_api_branches_count(test_username, repo_name)
51+ if skip_remote_repo {
52+ ilog ('Skipping the remote repository clone tests (GITLY_TEST_SKIP_REMOTE_REPO is set)' )
53+ } else {
54+ repo_name := 'test2'
55+ test_create_repo (token, repo_name, test_github_repo_url)
56+ // wait while repo is cloning
57+ time.sleep (5 * time.second)
58+ // get repo
59+ assert get_repo_commit_count (token, test_username, repo_name,
60+ test_github_repo_primary_branch) > 0
61+ assert get_repo_issue_count (token, test_username, repo_name) == 0
62+ assert get_repo_branch_count (token, test_username, repo_name) > 0
63+ test_repo_page (test_username, repo_name)
64+ test_branch_page (test_username, repo_name, test_github_repo_primary_branch)
65+ test_repos_page (test_username)
66+ test_repo_settings_page (test_username, repo_name)
67+ test_contributors_page (test_username, repo_name)
68+ // test_issues_page(test_username)
69+ test_stars_page (test_username)
70+ test_settings_page (test_username)
71+ test_commits_page (test_username, repo_name, test_github_repo_primary_branch)
72+ test_branches_page (test_username, repo_name)
73+ test_repo_tree (test_username, repo_name, test_github_repo_primary_branch, 'c' )
74+ // this makes sure that the blob (and the tree?) is ready
75+ test_repo_tree (test_username, repo_name, test_github_repo_primary_branch, 'examples' )
76+ test_blob_page (test_username, repo_name, test_github_repo_primary_branch,
77+ 'examples/hello.v' )
78+ // test_refs_page(test_username, repo_name)
79+ // test_api_branches_count(test_username, repo_name)
80+ }
7081 ilog ('all tests passed!' )
7182
72- after ()!
83+ after (mut gitly_process )!
7384}
7485
75- fn before () ! {
86+ fn before () ! & os.Process {
7687 cd_executable_dir ()!
7788
7889 ilog ('Make sure gitly is not running' )
@@ -83,24 +94,37 @@ fn before() ! {
8394 compile_gitly ()
8495
8596 ilog ('Start gitly in the background, then wait till gitly starts and is responding to requests' )
86- spawn run_gitly ()
97+ mut gitly_process := start_gitly ()
8798
88- wait_gitly ()
89- }
99+ wait_gitly (mut gitly_process)
90100
91- fn after () ! {
92- remove_database_if_exists ()!
93- remove_repos_dir_if_exists ()!
101+ return gitly_process
102+ }
94103
104+ fn after (mut gitly_process os.Process) ! {
95105 ilog ('Ensure gitly is stopped' )
106+ if gitly_process.is_alive () {
107+ gitly_process.signal_kill ()
108+ }
109+ gitly_process.wait ()
110+ // A best effort fallback, in case an older instance is still lingering:
96111 kill_gitly_processes ()
112+
113+ // Only remove the DB/repos after gitly has released them, otherwise the
114+ // files are still locked on Windows and the removal fails.
115+ remove_database_if_exists ()!
116+ remove_repos_dir_if_exists ()!
97117}
98118
99- fn run_gitly () {
100- gitly_process := os.execute ('./gitly.exe &' )
101- if gitly_process.exit_code != 0 {
102- exit_with_message (gitly_process.str ())
103- }
119+ // start_gitly launches the freshly compiled gitly.exe as a background process.
120+ // It uses os.new_process (instead of a shell `&`), so that it works the same
121+ // way on Windows, macOS and Linux, and so the process can be stopped later.
122+ fn start_gitly () & os.Process {
123+ gitly_exe := os.join_path (os.getwd (), 'gitly.exe' )
124+ mut gitly_process := os.new_process (gitly_exe)
125+ gitly_process.set_work_folder (os.getwd ())
126+ gitly_process.run ()
127+ return gitly_process
104128}
105129
106130@[noreturn]
@@ -122,7 +146,11 @@ fn cd_executable_dir() ! {
122146}
123147
124148fn kill_gitly_processes () {
125- os.execute ('pkill -9 gitly.exe' )
149+ $if windows {
150+ os.execute ('taskkill /F /IM gitly.exe' )
151+ } $else {
152+ os.execute ('pkill -9 gitly.exe' )
153+ }
126154}
127155
128156fn remove_database_if_exists () ! {
@@ -143,18 +171,35 @@ fn remove_repos_dir_if_exists() ! {
143171
144172fn compile_gitly () {
145173 ilog ('Compile gitly' )
146- // Note that using `-d use_openssl` prevents tcc from working, so the compilation will be much slower:
147- os.execute ('v -d use_libbacktrace -cg -keepc -d use_openssl -o gitly.exe .' )
174+ // Use the same V compiler that is running this test.
175+ vexe := os.getenv_opt ('VEXE' ) or { @VEXE }
176+ // `-d sqlite` makes gitly use an embedded sqlite database instead of the
177+ // default PostgreSQL backend, so the test needs no external database.
178+ // Note that using `-d use_openssl` prevents tcc from working, so the compilation will be much slower.
179+ // On Windows, -d use_libbacktrace is skipped (libbacktrace is not available there) and the native
180+ // schannel https backend is used, so -d use_openssl is skipped as well.
181+ mut compile_cmd := '${os .quoted_path (vexe )} -d sqlite -keepc -o gitly.exe .'
182+ $if ! windows {
183+ compile_cmd = '${os .quoted_path (vexe )} -d sqlite -d use_libbacktrace -cg -keepc -d use_openssl -o gitly.exe .'
184+ }
185+ res := os.execute (compile_cmd)
186+ if res.exit_code != 0 {
187+ exit_with_message ('failed to compile gitly:\n ${res .output }' )
188+ }
148189 ilog ('Compiled gitly.exe, size: ${os .file_size ('gitly .exe ')}' )
149190}
150191
151- fn wait_gitly () {
152- for waiting_cycles := 0 ; waiting_cycles < 50 ; waiting_cycles++ {
192+ fn wait_gitly (mut gitly_process os.Process ) {
193+ for waiting_cycles := 0 ; waiting_cycles < 100 ; waiting_cycles++ {
153194 ilog ('\t wait: ${waiting_cycles }' )
154- time.sleep (100 * time.millisecond)
195+ if ! gitly_process.is_alive () {
196+ exit_with_message ('gitly exited before answering any request (exit code ${gitly_process .code }); this indicates a crash' )
197+ }
198+ time.sleep (200 * time.millisecond)
155199 http.get (prepare_url ('' )) or { continue }
156- break
200+ return
157201 }
202+ exit_with_message ('gitly did not start listening on ${gitly_url } in time' )
158203}
159204
160205fn prepare_url (path string ) string {
0 commit comments