Artifact dc47fbe2526ba52163e7c6d92e02a73fc59562168dd4bad4cf36063e02774901:
- File
conformance/sync_client_cases_test.go
— part of check-in
[8cc3d7c5e4]
at
2026-10-13 02:23:50
on branch test/conformance-01-drafts
— test(conformance): check the -01 drafts of artifact, repo-state and sync
Re-pin the conformance suite to draft-fossil-artifact-format-01, draft-fossil-repo-state-01 and draft-fossil-sync-protocol-01, copied byte for byte from zit check-in 100351e26c. The delta format has no -01 and stays on -00. The -00 errata are folded into -01 and are no longer pinned; the six -01 errata are pinned for the fossil 2.28 behavior they record. conformance/rfcs/README.md records where each copy came from.
The requirement tables are re-read against -01, and new cases cover the date tag's event time (repo-state ยง4.2 step 6), the Julian-day grammar, a delta manifest naming a delta, dropped reserved F cards, the trailing-punctuation retry, truncated payloads, errors N, a file card after a refused push, the end of a request after a failed login, and the answer to a gimme for private content.
No library behavior changes. Where -01 departs from fossil 2.28 and go-libfossil follows fossil (a cancelled, unparsable or 0 date tag), the cases are marked as deviations. The non-conformances the re-pin exposes are marked as gaps, tracked in #370, #371, #372, #373, #374 and #375. (user: [email protected], size: 3152) [annotate] [blame] [check-ins using] [more...]
package conformance import ( "os" "testing" ) // syncClientCase is a scripted exchange and what the draft says a client // does in it. type syncClientCase struct { Case op clientOp setup []string // SQL on the client's copy of F // replies are the scripted replies' card lines; see syncFixture.body. replies [][]string // raw, when set, builds the reply entities instead, for cases about // framing. raw func(fx *syncFixture) [][]byte ctype string // the replies' media type; uncompressed unless set want clientCheck // fc also runs fossil(1)'s client against the script, whose requests // must meet want. fc bool // fossil is set only when fossil(1)'s client does not do what the // case expects, and says why the case follows the draft. fossil string // deviates, for a case marked Deviation, is what go-libfossil does // instead; a run that is neither is fatal. deviates clientCheck } func (c syncClientCase) peer(fx *syncFixture) *scriptedPeer { p := &scriptedPeer{fx: fx, ctype: c.ctype} if p.ctype == "" { p.ctype = typeUncompressed } if c.raw != nil { p.replies = c.raw(fx) return p } for _, reply := range c.replies { p.replies = append(p.replies, fx.body(reply...)) } return p } // run runs fossil(1)'s client, for an fc case, then go-libfossil's. fatal // is a fossil(1) disagreement or a harness failure; problem is // go-libfossil's departure from the case. func (c syncClientCase) run(fx *syncFixture, ref *fossilReference, dir string) (fatal, problem error) { if ref != nil && c.fc { run, err := ref.runFossilClient(fx, c.op, c.setup, c.peer(fx), dir) if err != nil { return err, nil } if err := fossilAgrees(c.want(run), c.fossil); err != nil { return expectf("%v (fossil output %.300q)", err, run.output), nil } } run, err := runGoClient(fx, c.op, c.setup, c.peer(fx), dir) if err != nil { return nil, err } problem = c.want(run) if problem != nil && c.deviates != nil { if err := c.deviates(run); err != nil { return expectf("not the deviation the case names: %v", err), nil } } return nil, problem } func TestSyncClient(t *testing.T) { ref := newFossilReference(t) top := t.TempDir() fx := newSyncFixture(t, top) for _, c := range syncClientCases() { c.Case = markSync(c.Case) checkSync(t, c.Case, func() (error, error) { dir, err := os.MkdirTemp(top, "case") if err != nil { return err, nil } return c.run(fx, ref, dir) }) } } func syncClientCases() []syncClientCase { var all []syncClientCase for _, group := range [][]syncClientCase{ clientRoundCases(), clientPhantomCases(), clientGimmeCases(), clientTerminationCases(), clientFramingCases(), clientPayloadCases(), clientCardCases(), clientAuthCases(), clientFileCases(), clientCFileCases(), clientUVFileCases(), clientDeltaCases(), clientPrivateCases(), clientCloneCases(), clientCloneStallCases(), clientCloneErrorCases(), clientUVCases(), clientUVStatusCases(), clientMessageCases(), clientGateCases(), clientAdmissionCases(), clientPullOnlyCases(), clientShortUVIGotCases(), clientRefusalCases(), } { all = append(all, group...) } return all }