Fossil SCM

fossil-scm / test / json.test
Source Blame History 925 lines
6262761… rberteig 1 #
6262761… rberteig 2 # Copyright (c) 2016 D. Richard Hipp
6262761… rberteig 3 #
6262761… rberteig 4 # This program is free software; you can redistribute it and/or
6262761… rberteig 5 # modify it under the terms of the Simplified BSD License (also
6262761… rberteig 6 # known as the "2-Clause License" or "FreeBSD License".)
6262761… rberteig 7 #
6262761… rberteig 8 # This program is distributed in the hope that it will be useful,
6262761… rberteig 9 # but without any warranty; without even the implied warranty of
6262761… rberteig 10 # merchantability or fitness for a particular purpose.
6262761… rberteig 11 #
6262761… rberteig 12 # Author contact information:
6262761… rberteig 13 # [email protected]
6262761… rberteig 14 # http://www.hwaci.com/drh/
6262761… rberteig 15 #
6262761… rberteig 16 ############################################################################
6262761… rberteig 17 #
6262761… rberteig 18 # Test JSON Support
6262761… rberteig 19 #
6262761… rberteig 20
6262761… rberteig 21 # Make sure we have a build with the json command at all and that it
6262761… rberteig 22 # is not stubbed out. This assumes the current (as of 2016-01-27)
6262761… rberteig 23 # practice of eliminating all trace of the fossil json command when
6262761… rberteig 24 # not configured. If that changes, these conditions might not prevent
6262761… rberteig 25 # the rest of this file from running.
09a46c2… mistachkin 26 fossil test-th-eval "hasfeature json"
09a46c2… mistachkin 27
3c78252… mistachkin 28 if {[normalize_result] ne "1"} {
fa59221… mistachkin 29 puts "Fossil was not compiled with JSON support."
fa59221… mistachkin 30 test_cleanup_then_return
5d700c7… andybradford 31 }
5d700c7… andybradford 32
5d700c7… andybradford 33 # We need a JSON parser to effectively test the JSON produced by
5d700c7… andybradford 34 # fossil. It looks like the one from tcllib is exactly what we need.
5d700c7… andybradford 35 # On ActiveTcl, add it with teacup. On other platforms, YMMV.
5d700c7… andybradford 36 # teacup install json
5d700c7… andybradford 37 # teacup install json::write
a588e55… mistachkin 38 if {[catch {package require json}] != 0} then {
e4f854d… mistachkin 39 puts {
e4f854d… mistachkin 40 The "json" package for Tcl is not available.
e4f854d… mistachkin 41 Please see: https://core.tcl-lang.org/tcllib
e4f854d… mistachkin 42 }
a588e55… mistachkin 43 test_cleanup_then_return
a588e55… mistachkin 44 }
5d700c7… andybradford 45
5d700c7… andybradford 46 proc json2dict {txt} {
5d700c7… andybradford 47 set rc [catch {::json::json2dict $txt} result options]
5d700c7… andybradford 48 if {$rc != 0} {
09a46c2… mistachkin 49 protOut "JSON ERROR: $result"
5d700c7… andybradford 50 return {}
5d700c7… andybradford 51 }
5d700c7… andybradford 52 return $result
6262761… rberteig 53 }
6262761… rberteig 54
6262761… rberteig 55 # and that the json itself smells ok and has the expected API error code in it
09a46c2… mistachkin 56 fossil json -expectError
c35152a… rberteig 57 set JR [json2dict $RESULT]
c35152a… rberteig 58 if {$JR eq ""} {
fa59221… mistachkin 59 puts "Fossil was not compiled with JSON support (bad JSON)."
fa59221… mistachkin 60 test_cleanup_then_return
c35152a… rberteig 61 }
c35152a… rberteig 62 test json-1 {[dict exists $JR resultCode]
e9def3b… mistachkin 63 && [dict get $JR resultCode] in "FOSSIL-3002 FOSSIL-4102"}
6262761… rberteig 64
6262761… rberteig 65 # Use the CLI interface to execute a JSON command. Sets the global
6262761… rberteig 66 # RESULT to the response text, and JR to a Tcl dict conversion of the
6262761… rberteig 67 # response body.
6262761… rberteig 68 #
6262761… rberteig 69 # Returns "200" or "500".
6262761… rberteig 70 proc fossil_json {args} {
6262761… rberteig 71 global RESULT JR
6262761… rberteig 72 uplevel 1 fossil json {*}$args
c35152a… rberteig 73 set JR [json2dict $RESULT]
6262761… rberteig 74 return "200"
6262761… rberteig 75 }
6262761… rberteig 76
6262761… rberteig 77 # Use the HTTP interface to GET a JSON API URL. Sets the globals
6262761… rberteig 78 # RESULT to the HTTP response body, and JR to a Tcl dict conversion of
6262761… rberteig 79 # the response body.
09a46c2… mistachkin 80 #
6262761… rberteig 81 # Returns the status code from the HTTP header.
6262761… rberteig 82 proc fossil_http_json {url {cookie "Muppet=Monster"} args} {
6262761… rberteig 83 global RESULT JR
6262761… rberteig 84 set request "GET $url HTTP/1.1\r\nHost: localhost\r\nUser-Agent: Fossil-http-json\r\nCookie: $cookie"
a588e55… mistachkin 85 set RESULT [fossil_maybe_answer $request http {*}$args --ipaddr 127.0.0.1]
a588e55… mistachkin 86 set head ""; set body ""; set status "--NO_MATCH--"
6262761… rberteig 87 regexp {(?w)(.*)^\s*$(.*)} $RESULT dummy head body
6262761… rberteig 88 regexp {^HTTP\S+\s+(\d\d\d)\s+(.*)$} $head dummy status msg
6262761… rberteig 89 if {$status eq "200"} {
c35152a… rberteig 90 set JR [json2dict $body]
6262761… rberteig 91 }
6262761… rberteig 92 return $status
6262761… rberteig 93 }
6262761… rberteig 94
6262761… rberteig 95
6262761… rberteig 96 # Use the HTTP interface to POST a JSON API URL. Sets the globals
6262761… rberteig 97 # RESULT to the HTTP response body, and JR to a Tcl dict conversion of
6262761… rberteig 98 # the response body.
6262761… rberteig 99 #
6262761… rberteig 100 # Returns the status code from the HTTP header.
6262761… rberteig 101 proc fossil_post_json {url data {cookie "Muppet=Monster"} args} {
09a46c2… mistachkin 102 global RESULT JR
6262761… rberteig 103
6262761… rberteig 104 # set up a full GET or POST HTTP request
6262761… rberteig 105 set len [string length $data]
6262761… rberteig 106 if {$len > 0} {
6262761… rberteig 107 set request [subst {POST $url HTTP/1.0\r
6262761… rberteig 108 Host: localhost\r
6262761… rberteig 109 User-Agent: Fossil-Test\r
6262761… rberteig 110 Cookie: $cookie\r
6262761… rberteig 111 Content-Type: application/json
6262761… rberteig 112 Content-Length $len
6262761… rberteig 113 \r
6262761… rberteig 114 $data}]
6262761… rberteig 115 } else {
6262761… rberteig 116 set request [subst {GET $url HTTP/1.0\r
6262761… rberteig 117 Host: localhost\r
6262761… rberteig 118 User-Agent: Fossil-Test\r
6262761… rberteig 119 Cookie: $cookie\r
6262761… rberteig 120 \r
6262761… rberteig 121 }]
6262761… rberteig 122 }
6262761… rberteig 123
6262761… rberteig 124 # handle the actual request
6262761… rberteig 125 flush stdout
6262761… rberteig 126 #exec $fossilexe
a588e55… mistachkin 127 set RESULT [fossil_maybe_answer $request http {*}$args --ipaddr 127.0.0.1]
6262761… rberteig 128
6262761… rberteig 129 # separate HTTP headers from body
a588e55… mistachkin 130 set head ""; set body ""; set status "--NO_MATCH--"
6262761… rberteig 131 regexp {(?w)(.*)^\s*$(.*)} $RESULT dummy head body
6262761… rberteig 132 regexp {^HTTP\S+\s+(\d\d\d)\s+(.*)$} $head dummy status msg
6262761… rberteig 133 if {$status eq "200"} {
6262761… rberteig 134 if {[string length $body] > 0} {
c35152a… rberteig 135 set JR [json2dict $body]
6262761… rberteig 136 } else {
6262761… rberteig 137 set JR ""
6262761… rberteig 138 }
6262761… rberteig 139 }
6262761… rberteig 140 return $status
6262761… rberteig 141 }
6262761… rberteig 142
6262761… rberteig 143
6262761… rberteig 144 # Inspect a dict for keys it must have and keys it must not have
6262761… rberteig 145 proc test_dict_keys {testname D okfields badfields} {
9e5f06d… rberteig 146 if {$D eq ""} {
9e5f06d… rberteig 147 test $testname-validJSON 0
9e5f06d… rberteig 148 return
9e5f06d… rberteig 149 }
6262761… rberteig 150 set i 1
6262761… rberteig 151 foreach f $okfields {
6262761… rberteig 152 test "$testname-$i" {[dict exists $D $f]}
6262761… rberteig 153 incr i
6262761… rberteig 154 }
6262761… rberteig 155 foreach f $badfields {
6262761… rberteig 156 test "$testname-$i" {![dict exists $D $f]}
6262761… rberteig 157 incr i
6262761… rberteig 158 }
6262761… rberteig 159 }
6262761… rberteig 160
6262761… rberteig 161 # Inspect the envelope part of a returned JSON structure to confirm
6262761… rberteig 162 # that it has specific fields and that it lacks specific fields.
6262761… rberteig 163 proc test_json_envelope {testname okfields badfields} {
6262761… rberteig 164 test_dict_keys $testname $::JR $okfields $badfields
6262761… rberteig 165 }
6262761… rberteig 166
6262761… rberteig 167 # Inspect the envelope of a normal successful result
6262761… rberteig 168 proc test_json_envelope_ok {testname} {
6262761… rberteig 169 test_json_envelope $testname [concat fossil timestamp command procTimeUs \
6262761… rberteig 170 procTimeMs payload] [concat resultCode resultText]
6262761… rberteig 171 }
6262761… rberteig 172
6262761… rberteig 173 # Inspect the payload of a successful result to confirm that it has
6262761… rberteig 174 # specific fields and that it lacks specific fields.
6262761… rberteig 175 proc test_json_payload {testname okfields badfields} {
6262761… rberteig 176 test_dict_keys $testname [dict get $::JR payload] $okfields $badfields
6262761… rberteig 177 }
6262761… rberteig 178
6262761… rberteig 179 #### VERSION AKA HAI
6262761… rberteig 180
7db623e… danield 181 # The JSON API generally assumes we have a repository, so let it have one.
e5bcfd1… preben 182
e5bcfd1… preben 183 # Set FOSSIL_USER to ensure consistent results in "json user list"
e5bcfd1… preben 184 set _fossil_user ""
e5bcfd1… preben 185 if [info exists env(FOSSIL_USER)] {
e5bcfd1… preben 186 set _fossil_user $env(FOSSIL_USER)
e5bcfd1… preben 187 }
e5bcfd1… preben 188 set ::env(FOSSIL_USER) "JSON-TEST-USER"
e5bcfd1… preben 189
fa59221… mistachkin 190 test_setup
a588e55… mistachkin 191
a588e55… mistachkin 192 # Stop backoffice from running during this test as it can cause hangs.
a588e55… mistachkin 193 fossil settings backoffice-disable 1
6262761… rberteig 194
6262761… rberteig 195 # Check for basic envelope fields in the result with an error
6262761… rberteig 196 fossil_json -expectError
6262761… rberteig 197 test_json_envelope json-enverr [concat resultCode fossil timestamp \
6262761… rberteig 198 resultText command procTimeUs procTimeMs] {}
6262761… rberteig 199 test json-enverr-rc-1 {[dict get $JR resultCode] eq "FOSSIL-3002"}
6262761… rberteig 200
6262761… rberteig 201
6262761… rberteig 202 # Check for basic envelope fields in the result with a successful
6262761… rberteig 203 # command
6262761… rberteig 204 set HAIfields [concat manifestUuid manifestVersion manifestDate \
6262761… rberteig 205 manifestYear releaseVersion releaseVersionNumber \
6262761… rberteig 206 resultCodeParanoiaLevel jsonApiVersion]
6262761… rberteig 207
6262761… rberteig 208 fossil_json HAI
6262761… rberteig 209 test_json_envelope_ok json-HAI
6262761… rberteig 210 test_json_payload json-HAI $HAIfields {}
6262761… rberteig 211 test json-HAI-api {[dict get $JR payload jsonApiVersion] >= 20120713}
6262761… rberteig 212
6262761… rberteig 213 # Check for basic envelope fields in a HTTP result with a successful
6262761… rberteig 214 # command
6262761… rberteig 215 fossil_http_json /json/HAI
6262761… rberteig 216 test_json_envelope_ok json-http-HAI
6262761… rberteig 217 test_json_payload json-http-HAI $HAIfields {}
6262761… rberteig 218 test json-http-HAI-api {[dict get $JR payload jsonApiVersion] >= 20120713}
6262761… rberteig 219
6262761… rberteig 220 fossil_json version
6262761… rberteig 221 test_json_envelope_ok json-version
6262761… rberteig 222 test_json_payload json-version $HAIfields {}
6262761… rberteig 223 test json-version-api {[dict get $JR payload jsonApiVersion] >= 20120713}
6262761… rberteig 224
6262761… rberteig 225 #### ARTIFACT
6262761… rberteig 226
6262761… rberteig 227 # sha1 of 0 bytes and a file to match in a commit
6262761… rberteig 228 set UUID_empty da39a3ee5e6b4b0d3255bfef95601890afd80709
5ad7038… rberteig 229 # sha3 of 0 bytes and a file to match in a commit
5ad7038… rberteig 230 set UUID_empty_64 a7ffc6f8bf1ed76651c14756a061d662f580ff4de43b49fa82d80a4b80f8434a
6262761… rberteig 231 write_file empty ""
6262761… rberteig 232 fossil add empty
6262761… rberteig 233 fossil ci -m "empty file"
6262761… rberteig 234
6262761… rberteig 235 # json artifact (checkin)
6262761… rberteig 236 fossil_json [concat artifact tip]
6262761… rberteig 237 test_json_envelope_ok json-artifact-checkin-env
6262761… rberteig 238 test json-artifact-checkin {[dict get $JR payload type] eq "checkin"}
6262761… rberteig 239 test_json_payload json-artifact \
6262761… rberteig 240 [concat type uuid isLeaf timestamp user comment parents tags files] {}
6262761… rberteig 241
6262761… rberteig 242 # json artifact (file)
5ad7038… rberteig 243 fossil_json [concat artifact $UUID_empty_64]
6262761… rberteig 244 test_json_envelope_ok json-artifact-file-env
6262761… rberteig 245 test json-artifact-file {[dict get $JR payload type] eq "file"}
6262761… rberteig 246 test_json_payload json-artifact [concat type uuid size checkins] {}
6262761… rberteig 247
6262761… rberteig 248 # json artifact (wiki)
6262761… rberteig 249 fossil wiki create Empty <<"-=BLANK=-"
6262761… rberteig 250 fossil_json wiki get Empty
6262761… rberteig 251 test json-wiki-get {[dict get $JR payload name] eq "Empty"}
6262761… rberteig 252 set uuid [dict get $JR payload uuid]
6262761… rberteig 253 fossil_json artifact $uuid
6262761… rberteig 254 test_json_envelope_ok json-artifact-wiki-env
6262761… rberteig 255 test json-artifact-wiki {[dict get $JR payload type] eq "wiki"}
6262761… rberteig 256 test_json_payload json-artifact-wiki [list type uuid artifact] {}
6262761… rberteig 257 set artifact [dict get $JR payload artifact]
6262761… rberteig 258 test_dict_keys json-artifact-wiki-artifact $artifact \
6262761… rberteig 259 [list name uuid user timestamp size] {}
6262761… rberteig 260 # name, uuid, parent?, user, timestamp, size?, content?
6262761… rberteig 261
6262761… rberteig 262
6262761… rberteig 263 #### AUTHENTICATION
6262761… rberteig 264 fossil_json anonymousPassword
6262761… rberteig 265 test_json_envelope_ok json-anonymousPassword-env
6262761… rberteig 266 test_json_payload json-anonymousPassword {seed password} {}
6262761… rberteig 267 set seed [dict get $JR payload seed]
6262761… rberteig 268 set pass [dict get $JR payload password]
6262761… rberteig 269
6262761… rberteig 270 write_file anon-1 [subst {
6262761… rberteig 271 {
6262761… rberteig 272 "command":"login",
6262761… rberteig 273 "payload":{
6262761… rberteig 274 "name":"anonymous",
6262761… rberteig 275 "anonymousSeed":$seed,
6262761… rberteig 276 "password":"$pass"
6262761… rberteig 277 }
6262761… rberteig 278 }
6262761… rberteig 279 }]
6262761… rberteig 280 fossil_json --json-input anon-1
6262761… rberteig 281 test_json_envelope_ok json-login-a-env
6262761… rberteig 282 test_json_payload json-login-a {authToken name capabilities loginCookieName} {}
6262761… rberteig 283 set AuthAnon [dict get $JR payload]
6262761… rberteig 284 proc test_hascaps {testname need caps} {
6262761… rberteig 285 foreach n [split $need {}] {
6262761… rberteig 286 test $testname-$n {[string first $n $caps] >= 0}
6262761… rberteig 287 }
6262761… rberteig 288 }
271a978… preben 289 test_hascaps json-login-c "hz" [dict get $AuthAnon capabilities]
6262761… rberteig 290
6262761… rberteig 291 fossil user new U1 User-1 Uone
6262761… rberteig 292 fossil user capabilities U1 s
6262761… rberteig 293 write_file u1 {
6262761… rberteig 294 {
6262761… rberteig 295 "command":"login",
6262761… rberteig 296 "payload":{
6262761… rberteig 297 "name":"U1",
6262761… rberteig 298 "password":"Uone"
6262761… rberteig 299 }
6262761… rberteig 300 }
6262761… rberteig 301 }
6262761… rberteig 302 fossil_json --json-input u1
6262761… rberteig 303 test_json_envelope_ok json-login-u1-env
6262761… rberteig 304 test_json_payload json-login-u1 {authToken name capabilities loginCookieName} {}
6262761… rberteig 305 set AuthU1 [dict get $JR payload]
6262761… rberteig 306 test_hascaps json-login-c "s" [dict get $AuthU1 capabilities]
6262761… rberteig 307
6262761… rberteig 308 set U1Cookie [dict get $AuthU1 loginCookieName]=[regsub -all {[/]} [dict get $AuthU1 authToken] {%2F} ]
6262761… rberteig 309 set AnonCookie [dict get $AuthAnon loginCookieName]=[regsub -all {[/]} [dict get $AuthAnon authToken] {%2F} ]
6262761… rberteig 310
6262761… rberteig 311 # json cap
6262761… rberteig 312 # The CLI user has all rights, and no auth token affects that. This
6262761… rberteig 313 # is consistent with the rest of the fossil CLI, and with the
6262761… rberteig 314 # pragmatic argument that using the CLI implies physical access to
6262761… rberteig 315 # the repo file itself, which can be taunted with many tools
6262761… rberteig 316 # including raw SQLite which will also ignore authentication.
6262761… rberteig 317 write_file anon-2 [subst {
6262761… rberteig 318 {"command":"cap",
6262761… rberteig 319 "authToken":"[dict get $AuthAnon authToken]"
6262761… rberteig 320 }
6262761… rberteig 321 }]
6262761… rberteig 322 fossil_json --json-input anon-2
6262761… rberteig 323 test_json_envelope_ok json-cap-env
6262761… rberteig 324 test json-cap-CLI {[dict get $JR payload permissionFlags setup]}
6262761… rberteig 325
6262761… rberteig 326 # json cap via POST with authToken in request envelope
6262761… rberteig 327 set anon2 [read_file anon-2]
6262761… rberteig 328 fossil_post_json "/json/cap" $anon2
6262761… rberteig 329 test json-cap-POSTenv-env-0 {[string length $JR] > 0}
6262761… rberteig 330 test_json_envelope_ok json-cap-POSTenv-env
a588e55… mistachkin 331 if {[catch {test json-cap-POSTenv-name \
a588e55… mistachkin 332 {[dict get $JR payload name] eq "anonymous"} knownBug} jerr]} then {
a588e55… mistachkin 333 test json-cap-POSTenv-name-threw 0
a588e55… mistachkin 334 protOut "CAUGHT: $jerr"
a588e55… mistachkin 335 }
6262761… rberteig 336 test json-cap-POSTenv-notsetup {![dict get $JR payload permissionFlags setup]}
6262761… rberteig 337
6262761… rberteig 338
6262761… rberteig 339 # json cap via GET with authToken in Cookie header
6262761… rberteig 340 fossil_post_json "/json/cap" {} $AnonCookie
6262761… rberteig 341 test json-cap-GETcookie-env-0 {[string length $JR] > 0}
a588e55… mistachkin 342 test_json_envelope_ok json-cap-GETcookie-env-0
a588e55… mistachkin 343 if {[catch {test json-cap-GETcookie-name-0 \
a588e55… mistachkin 344 {[dict get $JR payload name] eq "anonymous"}} jerr]} then {
a588e55… mistachkin 345 test json-cap-GETcookie-name-0-threw 0
a588e55… mistachkin 346 protOut "CAUGHT: $jerr"
a588e55… mistachkin 347 }
a588e55… mistachkin 348 test json-cap-GETcookie-notsetup-0 {![dict get $JR payload permissionFlags setup]}
6262761… rberteig 349
6262761… rberteig 350
6262761… rberteig 351 # json cap via GET with authToken in a parameter
6262761… rberteig 352 fossil_post_json "/json/cap?authToken=[dict get $AuthAnon authToken]" {}
a588e55… mistachkin 353 test json-cap-GETcookie-env-1 {[string length $JR] > 0}
a588e55… mistachkin 354 test_json_envelope_ok json-cap-GETcookie-env-1
a588e55… mistachkin 355 if {[catch {test json-cap-GETcookie-name-1 \
a588e55… mistachkin 356 {[dict get $JR payload name] eq "anonymous"}} jerr]} then {
a588e55… mistachkin 357 test json-cap-GETcookie-name-1-threw 0
a588e55… mistachkin 358 protOut "CAUGHT: $jerr"
a588e55… mistachkin 359 }
a588e55… mistachkin 360 test json-cap-GETcookie-notsetup-1 {![dict get $JR payload permissionFlags setup]}
6262761… rberteig 361
6262761… rberteig 362
6262761… rberteig 363 # whoami
6262761… rberteig 364 # via CLI with no auth token supplied
6262761… rberteig 365 fossil_json whoami
6262761… rberteig 366 test_json_envelope_ok json-whoami-cli-env
6262761… rberteig 367 test_json_payload json-whoami-cli {name capabilities} {}
6262761… rberteig 368 test json-whoami-cli-name {[dict get $JR payload name] eq "nobody"}
6262761… rberteig 369 test_hascaps json-whoami-cli-cap "gjorz" [dict get $JR payload capabilities]
6262761… rberteig 370
6262761… rberteig 371 #### BRANCHES
6262761… rberteig 372 # json branch list
6262761… rberteig 373 fossil_json branch list
6262761… rberteig 374 test_json_envelope_ok json-branch-list-env
6262761… rberteig 375 test_json_payload json-branch-list {range current branches} {}
6262761… rberteig 376 test json-branch-list-cur {[dict get $JR payload current] eq "trunk"}
6262761… rberteig 377 test json-branch-list-cnt {[llength [dict get $JR payload branches]] == 1}
6262761… rberteig 378 test json-branch-list-val {[dict get $JR payload branches] eq "trunk"}
6262761… rberteig 379
6262761… rberteig 380 # json branch create
6262761… rberteig 381 fossil_json branch create alpha --basis trunk
6262761… rberteig 382 test_json_envelope_ok json-branch-create-env
6262761… rberteig 383 test_json_payload json-branch-create {name basis rid uuid isPrivate} {}
6262761… rberteig 384
6262761… rberteig 385
6262761… rberteig 386 #### CONFIG
6262761… rberteig 387 # json config get AREA
6262761… rberteig 388 # AREAs are skin ticket project all skin-backup
6262761… rberteig 389 foreach a [list skin ticket project all skin-backup] {
09a46c2… mistachkin 390 fossil_json config get $a
6262761… rberteig 391 test_json_envelope_ok json-config-$a-env
6262761… rberteig 392 # payload depends on specific area and may be completely empty
6262761… rberteig 393 }
6262761… rberteig 394
6262761… rberteig 395 #### DIFFS
6262761… rberteig 396 # json diff v1 v2
6262761… rberteig 397
6262761… rberteig 398 write_file fish {
6262761… rberteig 399 ABCD goldfish
6262761… rberteig 400 }
6262761… rberteig 401 fossil add fish
6262761… rberteig 402 fossil ci -m "goldfish"
6262761… rberteig 403 fossil_json finfo fish
6262761… rberteig 404 set fishHist [dict get $JR payload checkins]
6262761… rberteig 405 set fishV1 [dict get [lindex $fishHist 0] uuid]
6262761… rberteig 406
6262761… rberteig 407 write_file fish {
6262761… rberteig 408 ABCD goldfish
6262761… rberteig 409 LMNO goldfish
6262761… rberteig 410 }
6262761… rberteig 411 fossil ci -m "goldfish"
6262761… rberteig 412 fossil_json finfo fish
6262761… rberteig 413 set fishHist [dict get $JR payload checkins]
6262761… rberteig 414 set fishV2 [dict get [lindex $fishHist 0] uuid]
6262761… rberteig 415
6262761… rberteig 416 test fossil-diff-setup {$fishV1 ne $fishV2}
6262761… rberteig 417 fossil_json diff $fishV1 $fishV2
6262761… rberteig 418 test_json_envelope_ok json-diff-env
6262761… rberteig 419 test_json_payload json-diff {from to diff} {}
6262761… rberteig 420 test json-diff-v1 {[dict get $JR payload from] eq $fishV1}
6262761… rberteig 421 test json-diff-v2 {[dict get $JR payload to] eq $fishV2}
6262761… rberteig 422 set diff [dict get $JR payload diff]
6262761… rberteig 423 test json-diff-diff {[string first "+LMNO goldfish" $diff] >= 0}
6262761… rberteig 424 protOut [dict get $JR payload diff]
6262761… rberteig 425
6262761… rberteig 426
6262761… rberteig 427 #### DIRECTORY LISTING
6262761… rberteig 428 # json dir DIRNAME
09a46c2… mistachkin 429 fossil_json dir
6262761… rberteig 430 test_json_envelope_ok json-dir-env
6262761… rberteig 431 test_json_payload json-dir {name entries} {}
6262761… rberteig 432
6262761… rberteig 433 #### FILE INFO
6262761… rberteig 434 # json finfo FILENAME
6262761… rberteig 435 fossil_json finfo empty
6262761… rberteig 436 test_json_envelope_ok json-finfo-env
6262761… rberteig 437 test_json_payload json-finfo {name checkins} {}
6262761… rberteig 438
6262761… rberteig 439 #### QUERY
6262761… rberteig 440 # json query SQLCODE
6262761… rberteig 441 fossil_json query {"SELECT * FROM reportfmt"}
6262761… rberteig 442 test_json_envelope_ok json-query-env
6262761… rberteig 443 test_json_payload json-query {columns rows} {}
6262761… rberteig 444
6262761… rberteig 445 #### STATS
6262761… rberteig 446 # json stat
6262761… rberteig 447 fossil_json stat
6262761… rberteig 448 test_json_envelope_ok json-stat-env
6262761… rberteig 449 test_json_payload json-stat {repositorySize ageDays ageYears projectCode compiler sqlite} \
6262761… rberteig 450 {blobCount deltaCount uncompressedArtifactSize averageArtifactSize maxArtifactSize \
6262761… rberteig 451 compressionRatio checkinCount fileCount wikiPageCount ticketCount}
6262761… rberteig 452
6262761… rberteig 453 fossil_json stat -f
6262761… rberteig 454 test_json_envelope_ok json-stat-env
6262761… rberteig 455 test_json_payload json-stat {repositorySize \
6262761… rberteig 456 blobCount deltaCount uncompressedArtifactSize averageArtifactSize maxArtifactSize \
6262761… rberteig 457 compressionRatio checkinCount fileCount wikiPageCount ticketCount \
6262761… rberteig 458 ageDays ageYears projectCode compiler sqlite} {}
6262761… rberteig 459
6262761… rberteig 460
6262761… rberteig 461 #### STATUS
6262761… rberteig 462 # NOTE: Local checkout required
6262761… rberteig 463 # json status
6262761… rberteig 464 fossil_json status
6262761… rberteig 465 test_json_envelope_ok json-status-env
6262761… rberteig 466 test_json_payload json-status {repository localRoot checkout files errorCount} {}
6262761… rberteig 467
6262761… rberteig 468 #### TAGS
6262761… rberteig 469
6262761… rberteig 470 # json tag add NAME CHECKIN VALUE
6262761… rberteig 471 fossil_json tag add blue trunk green
6262761… rberteig 472 test_json_envelope_ok json-tag-add-env
6262761… rberteig 473 test_json_payload json-tag-add {name value propagate raw appliedTo} {}
6262761… rberteig 474
6262761… rberteig 475
6262761… rberteig 476 # json tag cancel NAME CHECKIN
6262761… rberteig 477 fossil_json tag add cancel alpha
6262761… rberteig 478 test_json_envelope_ok json-tag-cancel-env
6262761… rberteig 479 # DOCBUG? Doc says no payload.
6262761… rberteig 480 test_json_payload json-tag-cancel {name value propagate raw appliedTo} {}
6262761… rberteig 481
6262761… rberteig 482 # json tag find NAME
6262761… rberteig 483 fossil_json tag find alpha
6262761… rberteig 484 test_json_envelope_ok json-tag-find-env
6262761… rberteig 485 test_json_payload json-tag-find {name raw type limit artifacts} {}
6262761… rberteig 486 test json-tag-find-count {[llength [dict get $JR payload artifacts]] >= 1}
6262761… rberteig 487
6262761… rberteig 488 # json tag list CHECKIN
6262761… rberteig 489 fossil_json tag list
6262761… rberteig 490 test_json_envelope_ok json-tag-list-env
6262761… rberteig 491 test_json_payload json-tag-list {raw includeTickets tags} {}
6262761… rberteig 492 test json-tag-list-count {[llength [dict get $JR payload tags]] >= 2}
6262761… rberteig 493
6262761… rberteig 494
6262761… rberteig 495 #### TICKETS
6262761… rberteig 496 # API Docs say not yet defined, so it isn't quite fair to mark this
6262761… rberteig 497 # category as TODO for the test cases...
6262761… rberteig 498
6262761… rberteig 499 #### TICKET REPORTS
6262761… rberteig 500
6262761… rberteig 501 # json report get NUMBER
6262761… rberteig 502 fossil_json report get 1
6262761… rberteig 503 test_json_envelope_ok json-report-get-env
6262761… rberteig 504 test_json_payload json-report-get {report owner title timestamp columns sqlCode} {}
6262761… rberteig 505
6262761… rberteig 506 # json report list
6262761… rberteig 507 fossil_json report list
6262761… rberteig 508 test_json_envelope_ok json-report-list-env
6262761… rberteig 509 #test_json_payload json-report-list {raw includeTickets tags} {}
6262761… rberteig 510 test json-report-list-count {[llength [dict get $JR payload]] >= 1}
6262761… rberteig 511
6262761… rberteig 512
6262761… rberteig 513 # json report run NUMBER
6262761… rberteig 514 fossil_json report run 1
6262761… rberteig 515 test_json_envelope_ok json-report-run-1-env
6262761… rberteig 516 test_json_payload json-report-list {report title sqlcode columnNames tickets} {}
6262761… rberteig 517 test json-report-list-count {[llength [dict get $JR payload columnNames]] >= 7}
6262761… rberteig 518 test json-report-list-count {[llength [dict get $JR payload tickets]] >= 0}
6262761… rberteig 519
6262761… rberteig 520
6262761… rberteig 521 #### TIMELINE
6262761… rberteig 522
6262761… rberteig 523 # json timeline checkin
6262761… rberteig 524 fossil_json timeline checkin
6262761… rberteig 525 test_json_envelope_ok json-timeline-checkin-env
6262761… rberteig 526 test_json_payload json-timeline-checkin {limit timeline} {}
6262761… rberteig 527 set i 0
6262761… rberteig 528 foreach t [dict get $JR payload timeline] {
6262761… rberteig 529 # parents appears only for entries that have a parent
6262761… rberteig 530 # files appears only if requested by the --files parameter
6262761… rberteig 531 test_dict_keys json-timeline-checkin-$i $t {type uuid timestamp comment user isLeaf tags} {}
6262761… rberteig 532 incr i
6262761… rberteig 533 }
6262761… rberteig 534
6262761… rberteig 535 # json timeline ci
6262761… rberteig 536 # removed from documentation
6262761… rberteig 537 #fossil_json timeline ci
6262761… rberteig 538 #test json-timeline-ci {[dict get $JR resultCode] ne "FOSSIL-1102"} knownBug
6262761… rberteig 539 #test_json_payload json-timeline-ci {limit timeline} {}
6262761… rberteig 540
6262761… rberteig 541 # json timeline ticket
6262761… rberteig 542 fossil_json timeline ticket
6262761… rberteig 543 test_json_envelope_ok json-timeline-ticket-env
6262761… rberteig 544 test_json_payload json-timeline-ticket {limit timeline} {}
6262761… rberteig 545
6262761… rberteig 546 # json timeline wiki
6262761… rberteig 547 fossil_json timeline wiki
6262761… rberteig 548 test_json_envelope_ok json-timeline-wiki-env
6262761… rberteig 549 test_json_payload json-timeline-wiki {limit timeline} {}
6262761… rberteig 550
6262761… rberteig 551
6262761… rberteig 552 #### USER MANAGEMENT
6262761… rberteig 553
6262761… rberteig 554 # json user get
6262761… rberteig 555 foreach u [list nobody anonymous reader developer U1] {
6262761… rberteig 556 fossil_json user get $u
6262761… rberteig 557 test_json_envelope_ok json-user-get-$u-env
6262761… rberteig 558 test_json_payload json-user-get-$u {uid name capabilities info timestamp} {}
6262761… rberteig 559 }
6262761… rberteig 560
6262761… rberteig 561 # json user list
6262761… rberteig 562 fossil_json user list
6262761… rberteig 563 test_json_envelope_ok json-user-list-env
6262761… rberteig 564 set i 0
6262761… rberteig 565 foreach u [dict get $JR payload] {
6262761… rberteig 566 test_dict_keys json-user-list-$i $u {uid name capabilities info timestamp} {}
6262761… rberteig 567 incr i
6262761… rberteig 568 }
6262761… rberteig 569
6262761… rberteig 570 # json user save
09a46c2… mistachkin 571 fossil_json user save --uid -1 --name U2 --password Utwo
6262761… rberteig 572 test_json_envelope_ok json-user-save-env
6262761… rberteig 573 test_json_payload json-user-save {uid name capabilities info timestamp} {}
6262761… rberteig 574
6262761… rberteig 575
6262761… rberteig 576 # DOCBUG? Doc says payload is "same as /json/user/get" but actual
6262761… rberteig 577 # result was an array of one user similar to /json/user/list.
6262761… rberteig 578 #set i 0
6262761… rberteig 579 #foreach u [dict get $JR payload] {
6262761… rberteig 580 # test_dict_keys json-user-save-$i $u {uid name capabilities info timestamp} {}
6262761… rberteig 581 # incr i
6262761… rberteig 582 #}
6262761… rberteig 583 #test json-user-save-count {$i == 1}
6262761… rberteig 584
6262761… rberteig 585
6262761… rberteig 586
6262761… rberteig 587 #### WIKI
6262761… rberteig 588
6262761… rberteig 589 # wiki list
6262761… rberteig 590 fossil_json wiki list
09a46c2… mistachkin 591 test_json_envelope_ok json-wiki-list-env
6262761… rberteig 592 set pages [dict get $JR payload]
6262761… rberteig 593 test json-wiki-1 {[llength $pages] == 1}
6262761… rberteig 594 test json-wiki-2 {[lindex $pages 0] eq "Empty"}
6262761… rberteig 595 fossil_json wiki list --verbose
6262761… rberteig 596 set pages [dict get $JR payload]
6262761… rberteig 597 test json-wiki-verbose-1 {[llength $pages] == 1}
6262761… rberteig 598 test_dict_keys json-wiki-verbose-pages [lindex $pages 0] [list name uuid user timestamp size] {}
6262761… rberteig 599
6262761… rberteig 600 # wiki get
6262761… rberteig 601 fossil_json wiki get Empty
09a46c2… mistachkin 602 test_json_envelope_ok json-wiki-get-env
6262761… rberteig 603 # this page has only one version, so no parent should be listed
6262761… rberteig 604 test_json_payload json-wiki-get [list name uuid user timestamp size content] [list parent]
6262761… rberteig 605
6262761… rberteig 606
6262761… rberteig 607 # wiki create
6262761… rberteig 608 # requires an authToken? Not from CLI.
6262761… rberteig 609
6262761… rberteig 610 write_file req.json {
6262761… rberteig 611 {
6262761… rberteig 612 "command":"wiki/create",
6262761… rberteig 613 "payload":{
6262761… rberteig 614 "name":"Page2",
6262761… rberteig 615 "content":"Lorem ipsum dolor sic amet."
6262761… rberteig 616 }
6262761… rberteig 617 }
6262761… rberteig 618 }
6262761… rberteig 619 fossil_json --json-input req.json
6262761… rberteig 620 test_json_envelope_ok json-wiki-create-env
6262761… rberteig 621 fossil_json wiki get Page2
6262761… rberteig 622 test_json_envelope_ok json-wiki-create-get-env
6262761… rberteig 623 test_json_payload json-wiki-save-get [list name uuid user timestamp size content] {parent}
6262761… rberteig 624 set uuid1 [dict get $JR payload uuid]
6262761… rberteig 625
6262761… rberteig 626 # wiki save
6262761… rberteig 627
6262761… rberteig 628 write_file req2.json {
6262761… rberteig 629 {
6262761… rberteig 630 "command":"wiki/save",
6262761… rberteig 631 "payload":{
6262761… rberteig 632 "name":"Page2",
6262761… rberteig 633 "content":"Lorem ipsum dolor sic amet.\nconsectetur adipisicing elit."
6262761… rberteig 634 }
6262761… rberteig 635 }
6262761… rberteig 636 }
6262761… rberteig 637 fossil_json --json-input req2.json
6262761… rberteig 638 test_json_envelope_ok json-wiki-save-env
6262761… rberteig 639 fossil_json wiki get Page2
6262761… rberteig 640 test_json_envelope_ok json-wiki-save-get-env
6262761… rberteig 641 test_json_payload json-wiki-save-get [list name uuid user timestamp size parent content] {}
6262761… rberteig 642 set uuid2 [dict get $JR payload uuid]
6262761… rberteig 643 test json-wiki-save-parent {[dict get $JR payload parent] eq $uuid1}
6262761… rberteig 644
6262761… rberteig 645 # wiki diff
6262761… rberteig 646
6262761… rberteig 647 fossil_json wiki diff $uuid1 $uuid2
6262761… rberteig 648 test_json_envelope_ok json-wiki-diff-env
6262761… rberteig 649 test_json_payload json-wiki-diff [list v1 v2 diff] {}
6262761… rberteig 650 test json-wiki-diff-v1 {[dict get $JR payload v1] eq $uuid1}
6262761… rberteig 651 test json-wiki-diff-v1 {[dict get $JR payload v2] eq $uuid2}
6262761… rberteig 652 set diff [dict get $JR payload diff]
c35152a… rberteig 653 test json-wiki-diff-diff {[string first "+consectetur adipisicing elit" $diff] >= 0}
6262761… rberteig 654 #puts [dict get $JR payload diff]
6262761… rberteig 655
6262761… rberteig 656 # wiki preview
6262761… rberteig 657 #
6262761… rberteig 658 # takes a string in fossil wiki markup and return an HTML fragment.
6262761… rberteig 659 # This command does not make use of the actual wiki content (much?)
6262761… rberteig 660 # at all.
6262761… rberteig 661 write_file req3.json {
6262761… rberteig 662 {
6262761… rberteig 663 "command":"wiki/preview",
6262761… rberteig 664 "payload":"Lorem ipsum dolor sic amet.\nconsectetur adipisicing elit."
6262761… rberteig 665 }
6262761… rberteig 666 }
6262761… rberteig 667 fossil_json --json-input req3.json
6262761… rberteig 668 test_json_envelope_ok json-wiki-preview-env
6262761… rberteig 669 set pv [dict get $JR payload]
6262761… rberteig 670 test json-wiki-preview-out-1 {[string first "<p>Lorem ipsum" $pv] == 0}
6262761… rberteig 671 test json-wiki-preview-out-2 {[string last "<p>" $pv] == 0}
6262761… rberteig 672
6262761… rberteig 673 #### UNAVOIDABLE MISC
6262761… rberteig 674
6262761… rberteig 675 # json g
6262761… rberteig 676 fossil_json g
6262761… rberteig 677 test_json_envelope_ok json-g-env
6262761… rberteig 678 #puts [llength [dict keys [dict get $JR payload]]]
6262761… rberteig 679 test json-g-g {[llength [dict keys [dict get $JR payload]]] >= 60};# 64 on my PC
6262761… rberteig 680
6262761… rberteig 681 # json rebuild
6262761… rberteig 682 fossil_json rebuild
6262761… rberteig 683 test_json_envelope json-rebuild-env [concat fossil timestamp command procTimeUs \
6262761… rberteig 684 procTimeMs] [concat payload resultCode resultText]
6262761… rberteig 685
6262761… rberteig 686 # json resultCodes
6262761… rberteig 687 fossil_json resultCodes
6262761… rberteig 688 test_json_envelope_ok json-resultCodes-env
6262761… rberteig 689 set codes [dict get $JR payload]
6262761… rberteig 690 test json-resultCodes-codes-1 {[llength $codes] >= 35} ;# count as of API 20120713
6262761… rberteig 691 # foreach c $codes {
6262761… rberteig 692 # puts [dict values $c]
6262761… rberteig 693 # }
6262761… rberteig 694 foreach r $codes {
6262761… rberteig 695 protOut "# [dict get $r resultCode] [dict get $r cSymbol]\n# [dict get $r description]"
6262761… rberteig 696 }
6262761… rberteig 697
6262761… rberteig 698
6262761… rberteig 699
6262761… rberteig 700 #### From the API Docs
6262761… rberteig 701
6262761… rberteig 702 # Reminder to self: in March 2012 i saw a corner-case which returns
6262761… rberteig 703 # HTML output. To reproduce: chmod 444 REPO, then submit a request
6262761… rberteig 704 # which writes something (timeline creates a temp table). The "repo
6262761… rberteig 705 # is not writable" error comes back as HTML. i don't know if the
6262761… rberteig 706 # error happens before we have made the determination that the app is
6262761… rberteig 707 # in JSON mode or if the error handling is incorrectly not
09a46c2… mistachkin 708 # recognizing JSON mode.
6262761… rberteig 709 #
fa59221… mistachkin 710 #test_setup x.fossil
a588e55… mistachkin 711 fossil_http_json /json/query?sql=PRAGMA%20repository.journal_mode%3Dwal $U1Cookie
6262761… rberteig 712 test json-ROrepo-1-1 {$CODE == 0}
6262761… rberteig 713 test json-ROrepo-1-2 {[regexp {\}\s*$} $RESULT]}
6262761… rberteig 714 test json-ROrepo-1-3 {![regexp {SQLITE_[A-Z]+:} $RESULT]}
6262761… rberteig 715 test_json_envelope_ok json-http-timeline1
a588e55… mistachkin 716 if {$is_windows} then {
a588e55… mistachkin 717 catch {exec attrib +r .rep.fossil}; # Windows
a588e55… mistachkin 718 } else {
a588e55… mistachkin 719 catch {exec chmod 444 .rep.fossil}; # Unix
a588e55… mistachkin 720 }
6262761… rberteig 721 protOut "chmod 444 repo"
a588e55… mistachkin 722 fossil_http_json /json/query?sql=PRAGMA%20repository.journal_mode%3Ddelete $U1Cookie -expectError --json-preserve-rc
6262761… rberteig 723 test json-ROrepo-2-1 {$CODE != 0}
a588e55… mistachkin 724 test json-ROrepo-2-2 {[regexp {\}\s*$} $RESULT]}
a588e55… mistachkin 725 test json-ROrepo-2-3 {![regexp {SQLITE_[A-Z]+:} $RESULT]}
6262761… rberteig 726 #test_json_envelope_ok json-http-timeline2
a588e55… mistachkin 727 if {$is_windows} then {
a588e55… mistachkin 728 catch {exec attrib -r .rep.fossil}; # Windows
a588e55… mistachkin 729 catch {exec attrib -r .rep.fossil-shm}
a588e55… mistachkin 730 catch {exec attrib -r .rep.fossil-wal}
a588e55… mistachkin 731 } else {
a588e55… mistachkin 732 catch {exec chmod 666 .rep.fossil}; # Unix
a588e55… mistachkin 733 catch {exec chmod 666 .rep.fossil-shm}
a588e55… mistachkin 734 catch {exec chmod 666 .rep.fossil-wal}
a588e55… mistachkin 735 }
a588e55… mistachkin 736 protOut "chmod 666 repo"
6262761… rberteig 737
6262761… rberteig 738 #### Result Codes
6262761… rberteig 739 # Test cases designed to stimulate each (documented) error code.
6262761… rberteig 740
09a46c2… mistachkin 741 # FOSSIL-0000
6262761… rberteig 742 # Not returned by any command. We generally verify that in the
6262761… rberteig 743 # test_json_envelope_ok command by verifying that the resultCode
6262761… rberteig 744 # field is not present. Should any JSON endpoint begin to use the
6262761… rberteig 745 # range reserved for non-fatal warnings, those tests will fail.
6262761… rberteig 746 #
6262761… rberteig 747 # Notice that code is not included in the list returned from
6262761… rberteig 748 # /json/resultCodes.
6262761… rberteig 749
6262761… rberteig 750
6262761… rberteig 751 # FOSSIL-1000 FSL_JSON_E_GENERIC
6262761… rberteig 752 # Generic error
6262761… rberteig 753
6262761… rberteig 754 # FOSSIL-1101 FSL_JSON_E_INVALID_REQUEST
6262761… rberteig 755 # Invalid request
6262761… rberteig 756 write_file e1101.json {
6262761… rberteig 757 ["command","nope"]
6262761… rberteig 758 }
6262761… rberteig 759 fossil_json --json-input e1101.json -expectError
6262761… rberteig 760 test json-RC-1101-array-CLI-exit {$CODE != 0}
6262761… rberteig 761 test_json_envelope json-RC-1101-array-env {fossil timestamp command procTimeUs \
6262761… rberteig 762 procTimeMs resultCode resultText} {payload}
6262761… rberteig 763 test json-RC-1101-array-code {[dict get $JR resultCode] eq "FOSSIL-1101"}
6262761… rberteig 764
6262761… rberteig 765 write_file e1101.json {
6262761… rberteig 766 "Not really a command but more of a suggestion"
6262761… rberteig 767 }
6262761… rberteig 768 fossil_json --json-input e1101.json -expectError
6262761… rberteig 769 test json-RC-1101-string-CLI-exit {$CODE != 0}
6262761… rberteig 770 test_json_envelope json-RC-1101-string-env {fossil timestamp command procTimeUs \
6262761… rberteig 771 procTimeMs resultCode resultText} {payload}
6262761… rberteig 772 test json-RC-1101-string-code {[dict get $JR resultCode] eq "FOSSIL-1101"}
6262761… rberteig 773
6262761… rberteig 774
6262761… rberteig 775
6262761… rberteig 776
6262761… rberteig 777 # FOSSIL-1102 FSL_JSON_E_UNKNOWN_COMMAND
6262761… rberteig 778 # Unknown command or subcommand
6262761… rberteig 779 fossil_json NoSuchEndpoint -expectError
6262761… rberteig 780 test json-RC-1102-CLI-exit {$CODE != 0}
6262761… rberteig 781 test_json_envelope json-RC-1102-env {fossil timestamp command procTimeUs \
6262761… rberteig 782 procTimeMs resultCode resultText} {payload}
6262761… rberteig 783 test json-RC-1102-code {[dict get $JR resultCode] eq "FOSSIL-1102"}
6262761… rberteig 784
6262761… rberteig 785 write_file e1102.json {
6262761… rberteig 786 {
6262761… rberteig 787 "command":"no/such/endpoint"
6262761… rberteig 788 }
6262761… rberteig 789 }
6262761… rberteig 790 fossil_json --json-input e1102.json -expectError
9e5f06d… rberteig 791 test json-env-RC-1102a-CLI-exit {$CODE != 0}
9e5f06d… rberteig 792 test_json_envelope json-env-RC-1102a-env {fossil timestamp command procTimeUs \
6262761… rberteig 793 procTimeMs resultCode resultText} {payload}
9e5f06d… rberteig 794 test json-env-RC-1102a-code {[dict get $JR resultCode] eq "FOSSIL-1102"}
6262761… rberteig 795
6262761… rberteig 796
6262761… rberteig 797 # FOSSIL-1103 FSL_JSON_E_UNKNOWN
6262761… rberteig 798 # Unknown error
6262761… rberteig 799
9e5f06d… rberteig 800 write_file bad.sql {
9e5f06d… rberteig 801 CREATE TABLE spam(a integer, b text);
9e5f06d… rberteig 802 }
9e5f06d… rberteig 803 exec $::fossilexe sqlite3 --no-repository bad.fossil <bad.sql
9e5f06d… rberteig 804 fossil_json HAI -R bad.fossil -expectError
9e5f06d… rberteig 805 test json-env-RC-1103-CLI-exit {$CODE != 0}
9e5f06d… rberteig 806 if { $JR ne "" } {
9e5f06d… rberteig 807 test_json_envelope json-env-RC-1103-env {fossil timestamp command procTimeUs \
9e5f06d… rberteig 808 procTimeMs resultCode resultText} {payload}
9e5f06d… rberteig 809 test json-env-RC-1103-code {[dict exists $JR resultCode]\
9e5f06d… rberteig 810 && [dict get $JR resultCode] eq "FOSSIL-1103"} knownBug
9e5f06d… rberteig 811 } else {
9e5f06d… rberteig 812 protOut "Want test case for FOSSIL-1103"
9e5f06d… rberteig 813 test json-RC-1103 0 knownBug
9e5f06d… rberteig 814 }
6262761… rberteig 815
6262761… rberteig 816 # FOSSIL-1104 FSL_JSON_E_TIMEOUT
6262761… rberteig 817 # Timeout reached
6262761… rberteig 818 # FOSSIL-1105 FSL_JSON_E_ASSERT
6262761… rberteig 819 # Assertion failed
6262761… rberteig 820 # FOSSIL-1106 FSL_JSON_E_ALLOC
6262761… rberteig 821 # Resource allocation failed
6262761… rberteig 822 # FOSSIL-1107 FSL_JSON_E_NYI
6262761… rberteig 823 # Not yet implemented
6262761… rberteig 824 # FOSSIL-1108 FSL_JSON_E_PANIC
6262761… rberteig 825 # x
6262761… rberteig 826 # FOSSIL-1109 FSL_JSON_E_MANIFEST_READ_FAILED
6262761… rberteig 827 # Reading artifact manifest failed
6262761… rberteig 828 # FOSSIL-1110 FSL_JSON_E_FILE_OPEN_FAILED
6262761… rberteig 829 # Opening file failed
6262761… rberteig 830
6262761… rberteig 831 # FOSSIL-2000 FSL_JSON_E_AUTH
6262761… rberteig 832 # Authentication error
6262761… rberteig 833 # FOSSIL-2001 FSL_JSON_E_MISSING_AUTH
6262761… rberteig 834 # Authentication info missing from request
6262761… rberteig 835 # FOSSIL-2002 FSL_JSON_E_DENIED
6262761… rberteig 836 # Access denied
6262761… rberteig 837 # FOSSIL-2003 FSL_JSON_E_WRONG_MODE
6262761… rberteig 838 # Request not allowed (wrong operation mode)
6262761… rberteig 839 # FOSSIL-2100 FSL_JSON_E_LOGIN_FAILED
6262761… rberteig 840 # Login failed
6262761… rberteig 841 # FOSSIL-2101 FSL_JSON_E_LOGIN_FAILED_NOSEED
6262761… rberteig 842 # Anonymous login attempt was missing password seed
6262761… rberteig 843 # FOSSIL-2102 FSL_JSON_E_LOGIN_FAILED_NONAME
6262761… rberteig 844 # Login failed - name not supplied
6262761… rberteig 845 # FOSSIL-2103 FSL_JSON_E_LOGIN_FAILED_NOPW
6262761… rberteig 846 # Login failed - password not supplied
6262761… rberteig 847 # FOSSIL-2104 FSL_JSON_E_LOGIN_FAILED_NOTFOUND
6262761… rberteig 848 # Login failed - no match found
6262761… rberteig 849
6262761… rberteig 850 # FOSSIL-3000 FSL_JSON_E_USAGE
6262761… rberteig 851 # Usage error
6262761… rberteig 852 # FOSSIL-3001 FSL_JSON_E_INVALID_ARGS
6262761… rberteig 853 # Invalid argument(s)
6262761… rberteig 854
6262761… rberteig 855 # FOSSIL-3002 FSL_JSON_E_MISSING_ARGS
6262761… rberteig 856 # Missing argument(s)
6262761… rberteig 857 write_file e3002.json {
6262761… rberteig 858 {"color":"yellow",
6262761… rberteig 859 "really":"no, blue",
6262761… rberteig 860 "number":42
6262761… rberteig 861 }
6262761… rberteig 862 }
6262761… rberteig 863 fossil_json --json-input e3002.json -expectError
6262761… rberteig 864 test json-RC-3002-strange-CLI-exit {$CODE != 0}
6262761… rberteig 865 test_json_envelope json-RC-3002-strange-env {fossil timestamp command procTimeUs \
6262761… rberteig 866 procTimeMs resultCode resultText} {payload}
6262761… rberteig 867 test json-RC-3002-strange-code {[dict get $JR resultCode] eq "FOSSIL-3002"}
6262761… rberteig 868
6262761… rberteig 869
6262761… rberteig 870 # FOSSIL-3003 FSL_JSON_E_AMBIGUOUS_UUID
6262761… rberteig 871 # Resource identifier is ambiguous
6262761… rberteig 872 # FOSSIL-3004 FSL_JSON_E_UNRESOLVED_UUID
6262761… rberteig 873 # Provided uuid/tag/branch could not be resolved
6262761… rberteig 874 # FOSSIL-3005 FSL_JSON_E_RESOURCE_ALREADY_EXISTS
6262761… rberteig 875 # Resource already exists
6262761… rberteig 876 # FOSSIL-3006 FSL_JSON_E_RESOURCE_NOT_FOUND
6262761… rberteig 877 # Resource not found
6262761… rberteig 878
6262761… rberteig 879 # FOSSIL-4000 FSL_JSON_E_DB
6262761… rberteig 880 # Database error
6262761… rberteig 881 # FOSSIL-4001 FSL_JSON_E_STMT_PREP
6262761… rberteig 882 # Statement preparation failed
6262761… rberteig 883 # FOSSIL-4002 FSL_JSON_E_STMT_BIND
6262761… rberteig 884 # Statement parameter binding failed
6262761… rberteig 885 # FOSSIL-4003 FSL_JSON_E_STMT_EXEC
6262761… rberteig 886 # Statement execution/stepping failed
6262761… rberteig 887 # FOSSIL-4004 FSL_JSON_E_DB_LOCKED
6262761… rberteig 888 # Database is locked
6262761… rberteig 889 # FOSSIL-4101 FSL_JSON_E_DB_NEEDS_REBUILD
6262761… rberteig 890 # Fossil repository needs to be rebuilt
6262761… rberteig 891
6262761… rberteig 892 # FOSSIL-4102 FSL_JSON_E_DB_NOT_FOUND
6262761… rberteig 893 # Fossil repository db file could not be found.
6262761… rberteig 894 fossil close
6262761… rberteig 895 fossil_json HAI -expectError
6262761… rberteig 896 test json-RC-4102-CLI-exit {$CODE != 0}
9e5f06d… rberteig 897 test_json_envelope json-RC-4102-CLI-exit {fossil timestamp command procTimeUs \
6262761… rberteig 898 procTimeMs resultCode resultText} {payload}
9e5f06d… rberteig 899 test json-RC-4102 {[dict get $JR resultCode] eq "FOSSIL-4102"}
6262761… rberteig 900
6262761… rberteig 901 # FOSSIL-4103 FSL_JSON_E_DB_NOT_VALID
6262761… rberteig 902 # Fossil repository db file is not valid.
6262761… rberteig 903 write_file nope.fossil {
6262761… rberteig 904 This is not a fossil repo. It ought to be a SQLite db with a well-known schema,
6262761… rberteig 905 but it is actually just a block of text.
fa59221… mistachkin 906 }
9e5f06d… rberteig 907 fossil_json HAI -R nope.fossil -expectError
9e5f06d… rberteig 908 test json-RC-4103-CLI-exit {$CODE != 0}
9e5f06d… rberteig 909 if { $JR ne "" } {
9e5f06d… rberteig 910 test_json_envelope json-RC-4103-CLI {fossil timestamp command procTimeUs \
9e5f06d… rberteig 911 procTimeMs resultCode resultText} {payload}
9e5f06d… rberteig 912 test json-RC-4103 {[dict get $JR resultCode] eq "FOSSIL-4103"}
9e5f06d… rberteig 913 } else {
9e5f06d… rberteig 914 test json-RC-4103 0 knownBug
9e5f06d… rberteig 915 }
fa59221… mistachkin 916
fa59221… mistachkin 917 ###############################################################################
fa59221… mistachkin 918
fa59221… mistachkin 919 test_cleanup
e5bcfd1… preben 920
e5bcfd1… preben 921 if { $_fossil_user eq "" } {
e5bcfd1… preben 922 unset ::env(FOSSIL_USER)
e5bcfd1… preben 923 } else {
e5bcfd1… preben 924 set ::env(FOSSIL_USER) $_fossil_user
e5bcfd1… preben 925 }

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button