<> <> <> DIRECTORY BasicTime, Camelot, Commander, CommandTool, Convert, File, FS, IO, Mach, PBasics, Process, Random, Rope, YggDID, YggDIDPrivate, YggDIDMap, YggDIDMapPrivate, YggLock, YggFixedNames, YggEnvironment, YggFile, YggFileStream, YggIndexMaint, YggInternal, YggMonitoringLog, YggRep, YggTransaction, YggVolatileObjectCache; NavTestImpl: CEDAR PROGRAM IMPORTS BasicTime, Commander, CommandTool, Convert, IO, Process, Random, Rope, YggDID, YggRep, YggVolatileObjectCache EXPORTS YggDID, YggTransaction, YggInternal = BEGIN ROPE: TYPE = Rope.ROPE; <> BigRope: ROPE _ "Four score and seven years ago, our fathers brought forth on this continent a new nation, conceived in liberty, and dedicated to the proposition that all men are created equal. Now we are engaged in a great blah blah blah"; LittleRopes: ARRAY [0..3) OF ROPE _ ["foo", "bar", "bleah"]; attrNameArray: ARRAY [0..8] OF ROPE _ ["attr0", "thisisattribute1", "two", "attribute three is fairly long", "but then again, attribute four is longer than three", "and attribute five is longer than three and four together", "6", "sept", "eight"]; fieldNameArray: ARRAY [1..5] OF ROPE _ [NIL, "field2", "field3", "the name for field 4 is quite long", "field5"]; DID: PUBLIC TYPE ~ REF DIDRep; DIDRep: PUBLIC TYPE ~ YggDIDPrivate.DIDRep; Document: TYPE = REF DocumentRep; DocumentRep: PUBLIC TYPE = YggDIDMapPrivate.DocumentRep; <<>> <<>> <<>> <> NextDID: DIDRep _ [33, 400]; KnownDIDs: LIST OF DIDStuff _ NIL; NumberOfKnownDIDs: INT _ 0; DIDStuff: TYPE = RECORD [ did: DID, doc: Document, contents: YggRep.TypedPrimitiveElement, attributes: LIST OF YggRep.Attribute _ NIL ]; NextTransCount: CARD _ 10001; <<>> <> GetNextTrans: PROC RETURNS [transID: YggTransaction.TransID] ~ { NextTransCount _ NextTransCount + 1; transID _ [top: [lowTicker: NextTransCount], bottom: []]; }; GetNextDID: PROC RETURNS [did: YggDID.DID] ~ { did _ NEW[YggDIDPrivate.DIDRep _ [NextDID.didHigh, NextDID.didLow]]; NextDID.didLow _ NextDID.didLow + 1; }; GetNextDIDWithEmptyDoc: PROC RETURNS [did: YggDID.DID, doc: Document, didStuff: LIST OF DIDStuff] ~ { did _ GetNextDID[]; doc _ NEW[DocumentRep _ [did: did, name: NIL, componentFiles: NIL]]; didStuff _ KnownDIDs _ CONS[[did: did, doc: doc], KnownDIDs]; NumberOfKnownDIDs _ NumberOfKnownDIDs + 1; }; DoCommit: PROC [transID: YggTransaction.TransID] ~ { ERROR; }; <<>> <> <<>> NavTestProc: Commander.CommandProc = { <<[cmd: Handle] RETURNS [result: REF _ NIL, msg: ROPE _ NIL]>> <> MakeUpTPE: PROC RETURNS [tpe: YggRep.TypedPrimitiveElement] ~ { tpe.docType _ Random.ChooseInt[randomStream, 1, 8]; SELECT tpe.docType FROM YggRep.int => { tpe.bits _ NEW[INT _ Random.ChooseInt[randomStream, 1, 1066]]; }; YggRep.rope => { tpe.bits _ BigRope; }; YggRep.shortRope => { randr: INT = Random.ChooseInt[randomStream, 0, 2]; tpe.bits _ LittleRopes[randr]; }; YggRep.float => { rr: REAL32; ii: INT ; ii _ Random.ChooseInt[randomStream, 1, 1492]; rr _ ii; tpe.bits _ NEW[REAL32 _ rr]; }; YggRep.date => { newData: YggRep.AccurateGMT; newData _ NEW[YggRep.AccurateGMTRep _ [BasicTime.Now[], Random.ChooseInt[randomStream, 1, 1789]]]; tpe.bits _ newData; }; YggRep.did => { newDID: DID; newDID _ GetNextDID[]; tpe.bits _ newDID; }; YggRep.uninterpretedBytes => { noBytes: INT _ Random.ChooseInt[randomStream, 1, 1920]; theBytes: REF YggRep.BitsRep; theBytes _ NEW[YggRep.BitsRep[noBytes]]; theBytes.validBytes _ Random.ChooseInt[randomStream, 1, noBytes]; FOR byteNo: CARD IN [0..theBytes.validBytes) DO theBytes.b[byteNo] _ Random.ChooseInt[randomStream, 1, 255]; ENDLOOP; tpe.bits _ theBytes; }; 8 => { noBytes: INT _ Random.ChooseInt[randomStream, 1, 1920]; theBytes: REF YggRep.BitsRep; tpe.docType _ Random.ChooseInt[randomStream, YggRep.lastReservedDocType+1, YggRep.lastReservedDocType+1334]; theBytes _ NEW[YggRep.BitsRep[noBytes]]; theBytes.validBytes _ Random.ChooseInt[randomStream, 1, noBytes]; FOR byteNo: CARD IN [0..theBytes.validBytes) DO theBytes.b[byteNo] _ Random.ChooseInt[randomStream, 1, 255]; ENDLOOP; tpe.bits _ theBytes; }; ENDCASE => ERROR; }; CompareTPE: PROC [tpe1: YggRep.TypedPrimitiveElement, tpe2: YggRep.TypedPrimitiveElement] ~ { IF tpe1.docType # tpe2.docType THEN ERROR; SELECT tpe1.docType FROM YggRep.int => { vInt: REF INT; mInt: REF INT; vInt _ NARROW[tpe1.bits]; mInt _ NARROW[tpe2.bits]; IF vInt^ # mInt^ THEN ERROR; }; YggRep.rope => { biggaRope: ROPE; biggaRope _ NARROW[tpe1.bits]; IF ~Rope.Equal[biggaRope, BigRope] THEN ERROR; }; YggRep.shortRope => { smallaRope: ROPE; listRope: ROPE; smallaRope _ NARROW[tpe1.bits]; listRope _ NARROW[tpe2.bits]; IF ~Rope.Equal[smallaRope, listRope] THEN ERROR; }; YggRep.float => { vReal: REF REAL32; mReal: REF REAL32; vReal _ NARROW[tpe1.bits]; mReal _ NARROW[tpe2.bits]; IF vReal^ # mReal^ THEN ERROR; }; YggRep.date => { vDate: YggRep.AccurateGMT; mDate: YggRep.AccurateGMT; vDate _ NARROW[tpe1.bits]; mDate _ NARROW[tpe2.bits]; IF BasicTime.Period[vDate.gmt, mDate.gmt] # 0 THEN ERROR; IF vDate.usecs # mDate.usecs THEN ERROR; }; YggRep.did => { vDID: DID; mDID: DID; vDID _ NARROW[tpe1.bits]; mDID _ NARROW[tpe2.bits]; IF ~YggDID.EqualDIDs[vDID, mDID] THEN ERROR; }; YggRep.uninterpretedBytes => { vUnintBytes: REF YggRep.BitsRep; mUnintBytes: REF YggRep.BitsRep; vUnintBytes _ NARROW[tpe1.bits]; mUnintBytes _ NARROW[tpe2.bits]; IF vUnintBytes.validBytes # mUnintBytes.validBytes THEN ERROR; FOR byteNo: CARD IN [0..vUnintBytes.validBytes) DO IF vUnintBytes.b[byteNo] # mUnintBytes.b[byteNo] THEN ERROR; ENDLOOP; }; IN [YggRep.lastReservedDocType+1 .. YggRep.lastReservedDocType+1334] => { vUnintBytes: REF YggRep.BitsRep; mUnintBytes: REF YggRep.BitsRep; vUnintBytes _ NARROW[tpe1.bits]; mUnintBytes _ NARROW[tpe2.bits]; IF vUnintBytes.validBytes # mUnintBytes.validBytes THEN ERROR; FOR byteNo: CARD IN [0..vUnintBytes.validBytes) DO IF vUnintBytes.b[byteNo] # mUnintBytes.b[byteNo] THEN ERROR; ENDLOOP; }; ENDCASE => ERROR; }; CheckADID: PROC [lokd: LIST OF DIDStuff] ~ { vDoc: YggRep.VDoc _ NIL; trans: YggTransaction.TransID; vDocAttCount: INT _ 0; savedAttCount: INT _ 0; YggVolatileObjectCache.InvalidateDID[did: lokd.first.did, transID: YggEnvironment.nullTransID]; IF YggVolatileObjectCache.LookupDIDInCache[did: lokd.first.did, transID: YggEnvironment.nullTransID, mode: read] # NIL THEN ERROR; trans _ GetNextTrans[] ; vDoc _ YggRep.VolatizeFromDID[transID: trans, did: lokd.first.did, access: readOnly, lock: [read, wait], metaAttributesOnly: FALSE]; IF ~YggDID.EqualDIDs[vDoc.did, lokd.first.did] THEN ERROR; CompareTPE[vDoc.contents, lokd.first.contents]; FOR aL: LIST OF YggRep.Attribute _ lokd.first.attributes, aL.rest UNTIL aL = NIL DO FOR aLVDoc: LIST OF YggRep.Attribute _ vDoc.attributes, aLVDoc.rest UNTIL aLVDoc = NIL DO IF Rope.Equal[aL.first.attributeName, aLVDoc.first.attributeName] THEN { savedValue: LIST OF YggRep.AttributeValue _ aL.first.value; vDocValue: LIST OF YggRep.AttributeValue _ aLVDoc.first.value; FOR loav: LIST OF YggRep.AttributeValue _ vDocValue, loav.rest UNTIL loav = NIL DO savedValueSet: LIST OF YggRep.TypedPrimitiveElement; IF savedValue = NIL THEN ERROR; savedValueSet _ savedValue.first.valueSet; IF ~Rope.Equal[savedValue.first.fieldName, loav.first.fieldName] THEN ERROR; FOR vtpeList: LIST OF YggRep.TypedPrimitiveElement _ loav.first.valueSet, vtpeList.rest UNTIL vtpeList = NIL DO IF savedValueSet = NIL THEN ERROR; CompareTPE[vtpeList.first, savedValueSet.first]; savedValueSet _ savedValueSet.rest; ENDLOOP; IF savedValueSet # NIL THEN ERROR; savedValue _ savedValue.rest; ENDLOOP; IF savedValue # NIL THEN ERROR; EXIT; }; REPEAT FINISHED => ERROR; ENDLOOP; savedAttCount _ savedAttCount + 1; ENDLOOP; FOR aL: LIST OF YggRep.Attribute _ vDoc.attributes, aL.rest UNTIL aL = NIL DO vDocAttCount _ vDocAttCount + 1; ENDLOOP; IF vDocAttCount # savedAttCount THEN ERROR; DoCommit[trans]; }; argv: CommandTool.ArgumentVector; out: IO.STREAM; randomStream: Random.RandomStream; noisy: BOOL _ FALSE; offset: INT _ 0; noTests: INT; out _ cmd.out; argv _ CommandTool.Parse[cmd: cmd ! CommandTool.Failed => {msg _ errorMsg; GO TO failed}]; IF argv.argc < 2 THEN GOTO failed; IF Rope.InlineFetch[argv[1], 0] = '- THEN { c: CHAR; IF argv[1].Length[] # 2 THEN GOTO failed; c _ argv[1].InlineFetch[1] ; SELECT c FROM 'n => noisy _ TRUE; ENDCASE; offset _ 1; }; noTests _ Convert.IntFromRope[argv[1+offset] ! Convert.Error => GOTO failed]; KnownDIDs _ NIL; NumberOfKnownDIDs _ 0; NextDID.didHigh _ LOOPHOLE[BasicTime.Now[], PBasics.LongNumber].lo; [] _ GetNextDID[]; IF noTests <= 0 THEN RETURN; randomStream _ Random.Create[range: 16384, seed: -1] ; FOR loopCount: INT IN (0..noTests] DO rand: INT _ Random.ChooseInt[randomStream, 0, 24]; Process.CheckForAbort[]; IF loopCount = noTests THEN rand _ 0; SELECT rand FROM IN [0..3) => { -- volatalize and look up old did lokd: LIST OF DIDStuff; IF NumberOfKnownDIDs <= 0 THEN LOOP; FOR lokd _ KnownDIDs, lokd.rest UNTIL lokd = NIL DO CheckADID[lokd]; ENDLOOP; IF noisy THEN out.PutF["\nLook Up All Old Dids\n\n"]; }; IN [3..13) => { -- make new doc with a contents newDID: DID; doc: Document; didStuff: LIST OF DIDStuff; contents: YggRep.TypedPrimitiveElement; vDoc: YggRep.VDoc; trans: YggTransaction.TransID; trans _ GetNextTrans[] ; [newDID, doc, didStuff] _ GetNextDIDWithEmptyDoc[]; vDoc _ YggRep.VolatizeFromDID[trans, newDID, readWrite, [write, wait]]; contents _ MakeUpTPE[]; didStuff.first.contents _ contents; vDoc.contents _ contents; vDoc.contentsChanged _ TRUE; DoCommit[trans]; IF noisy THEN out.PutF["Make new doc: did= %g\n", IO.card[newDID.didLow] ]; }; IN [8..16) => { -- volatalize and look up old did rand: INT; lokd: LIST OF DIDStuff; IF NumberOfKnownDIDs <= 0 THEN LOOP; rand _ Random.ChooseInt[randomStream, 0, MIN[16384, NumberOfKnownDIDs]]; FOR lokd _ KnownDIDs, lokd.rest UNTIL lokd = NIL DO rand _ rand - 1; IF rand <= 0 THEN EXIT; ENDLOOP; IF lokd = NIL THEN LOOP; CheckADID[lokd]; IF noisy THEN out.PutF["look up old did: did= %g\n", IO.card[lokd.first.did.didLow] ]; }; IN [16..24) => { -- add attribute to did rand: INT; trans: YggTransaction.TransID; lokd: LIST OF DIDStuff; attrName: ROPE; noAttrVals: INT ; property: YggRep.Attribute; fieldTaken: ARRAY [1..5] OF BOOL _ ALL[FALSE]; vDoc: YggRep.VDoc _ NIL; IF NumberOfKnownDIDs <= 0 THEN LOOP; rand _ Random.ChooseInt[randomStream, 0, MIN[16384, NumberOfKnownDIDs]]; FOR lokd _ KnownDIDs, lokd.rest UNTIL lokd = NIL DO rand _ rand - 1; IF rand <= 0 THEN EXIT; ENDLOOP; IF lokd = NIL THEN LOOP; trans _ GetNextTrans[] ; vDoc _ YggRep.VolatizeFromDID[transID: trans, did: lokd.first.did, access: readWrite, lock: [write, wait], metaAttributesOnly: FALSE]; IF ~YggDID.EqualDIDs[vDoc.did, lokd.first.did] THEN ERROR; IF vDoc.contents.docType # lokd.first.contents.docType THEN ERROR; FOR tryNo: INT IN [0..7] DO propExists: BOOL _ FALSE; rand _ Random.ChooseInt[randomStream, 0, 8]; attrName _ attrNameArray[rand]; FOR aL: LIST OF YggRep.Attribute _ vDoc.attributes, aL.rest UNTIL aL = NIL DO IF Rope.Equal[aL.first.attributeName, attrName] THEN { propExists _ TRUE; EXIT; }; ENDLOOP; IF ~propExists THEN EXIT; attrName _ NIL; ENDLOOP; IF attrName = NIL THEN {DoCommit[trans]; LOOP;}; noAttrVals _ Random.ChooseInt[randomStream, 1, 5]; property.value _ NIL; FOR attrValNo: INT IN [0..noAttrVals) DO attrVal: YggRep.AttributeValue; fni: INT; fni _ noAttrVals _ Random.ChooseInt[randomStream, 1, 5]; IF fieldTaken[fni] THEN LOOP; fieldTaken[fni] _ TRUE; attrVal.fieldName _ fieldNameArray[fni]; attrVal.valueSet _ NIL; FOR tpeNo: INT IN [1..fni] DO attrVal.valueSet _ CONS[MakeUpTPE[], attrVal.valueSet]; ENDLOOP; property.value _ CONS[attrVal, property.value]; ENDLOOP; property.attributeName _ attrName; vDoc.attributes _ CONS[property, vDoc.attributes]; lokd.first.attributes _ CONS[property, lokd.first.attributes]; vDoc.namesOfAttributesChanged _ LIST[attrName]; DoCommit[trans]; IF noisy THEN out.PutF["add attribute to old did: did= %g\n", IO.card[lokd.first.did.didLow]]; }; ENDCASE; ENDLOOP; EXITS failed => {result _ $Failure}; }; <> Init: PROC = { Commander.Register["NavTest", NavTestProc, "NavTest noTests"]; }; Init[]; END. <<>>