<> <> <> DIRECTORY BasicTime, Camelot, Commander, CommandTool, Convert, File, FS, IO, Mach, PBasics, Process, Random, Rope, YggDID, YggDIDPrivate, YggDIDMap, YggDIDMapPrivate, YggdrasilInit, YggLock, YggFixedNames, YggEnvironment, YggFile, YggFileStream, YggIndexMaint, YggInternal, YggMonitoringLog, YggNav, YggRep, YggTransaction, YggVolatileObjectCache; NavTestImpl: CEDAR PROGRAM IMPORTS BasicTime, Commander, CommandTool, Convert, IO, Process, Random, Rope, YggDID, YggDIDMap, YggdrasilInit, YggNav, YggRep, YggVolatileObjectCache EXPORTS YggDID, 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"]; linkTypes: ARRAY [0..8] OF ROPE _ [NIL, "refersTo", "author", "the name for link number three is quite long", "foo", "zorch", "grumble", "hype", "rtext"]; DID: PUBLIC TYPE ~ REF DIDRep; DIDRep: PUBLIC TYPE ~ YggDIDPrivate.DIDRep; Document: TYPE = REF DocumentRep; DocumentRep: PUBLIC TYPE = YggDIDMapPrivate.DocumentRep; <<>> <> RandomSequenceSize: INT = 20; <<1) make a new object with int contents of 77>> <<1a) bug: now it looks it up>> <<2) add one attribute to it: "two" with two values: (NIL with a "foo", and field2 with a did of 1234 and a string of bar)>> RandomSequence: ARRAY [0..RandomSequenceSize) OF INT _ [3, 1, 77, 16, 0, 2, 2, 1, 3, 0, 2, 6, 1234, 3, 1, 13, 0, 52, 4, 77]; KnownDIDs: LIST OF DIDStuff _ NIL; linkStuff: TYPE = RECORD [ linkType: ROPE, linkDID: YggDID.DID, otherDID: YggDID.DID ]; NumberOfKnownDIDs: INT _ 0; DIDStuff: TYPE = RECORD [ did: DID, contents: YggRep.TypedPrimitiveElement, attributes: LIST OF YggRep.Attribute _ NIL, outlinks: LIST OF linkStuff, inlinks: LIST OF linkStuff, containers: LIST OF DID ]; <<>> <> <<>> NavTestProc: Commander.CommandProc = { <<[cmd: Handle] RETURNS [result: REF _ NIL, msg: ROPE _ NIL]>> <> randomIndex: INT _ 0; RandomChooseInt: PROC [rs: Random.RandomStream _ NIL, min: INT _ 0, max: INT] RETURNS [int: INT] ~ { IF fixedRandom THEN { v: INT; v _ RandomSequence[randomIndex]; IF v >= min AND v <= max THEN int _ v ELSE { v _ v MOD (max-min); v _ v + min; }; IF v < min OR v > max THEN ERROR; int _ v; randomIndex _ (randomIndex + 1) MOD RandomSequenceSize; } ELSE RETURN[Random.ChooseInt[rs, min, max]]; }; MakeUpTPE: PROC RETURNS [tpe: YggRep.TypedPrimitiveElement] ~ { tpe.docType _ RandomChooseInt[randomStream, 1, 8]; SELECT tpe.docType FROM YggRep.int => { tpe _ YggNav.ConstructIntTPE[RandomChooseInt[randomStream, 1, 1066]]; <> }; YggRep.rope => { tpe _ YggNav.ConstructRopeTPE[BigRope]; <> }; YggRep.shortRope => { randr: INT = RandomChooseInt[randomStream, 0, 2]; tpe _ YggNav.ConstructShortRopeTPE[LittleRopes[randr]]; <> }; YggRep.float => { rr: REAL32; ii: INT ; ii _ RandomChooseInt[randomStream, 1, 1492]; rr _ ii; <> tpe _ YggNav.ConstructFloatTPE[rr]; }; YggRep.date => { newData: YggRep.AccurateGMT; newData _ NEW[YggRep.AccurateGMTRep _ [BasicTime.Now[], RandomChooseInt[randomStream, 1, 1789]]]; <> tpe _ YggNav.ConstructDateTPE[newData^]; }; YggRep.did => { newDID: DID; newDID _ NEW[YggDIDPrivate.DIDRep _ [412, RandomChooseInt[randomStream, 1, 1970]]]; tpe.bits _ newDID; }; YggRep.uninterpretedBytes => { noBytes: INT _ RandomChooseInt[randomStream, 1, 1920]; theBytes: REF YggRep.BitsRep; theBytes _ NEW[YggRep.BitsRep[noBytes]]; theBytes.validBytes _ RandomChooseInt[randomStream, 1, noBytes]; FOR byteNo: CARD IN [0..theBytes.validBytes) DO theBytes.b[byteNo] _ RandomChooseInt[randomStream, 1, 255]; ENDLOOP; <> TRUSTED {tpe _ YggNav.ConstructUninterpretedBytesTPE[YggRep.uninterpretedBytes, LOOPHOLE[theBytes, LONG POINTER] + UNITS[YggRep.BitsRep[0]], noBytes];}; }; 8 => { noBytes: INT _ RandomChooseInt[randomStream, 1, 1920]; theBytes: REF YggRep.BitsRep; tpe.docType _ RandomChooseInt[randomStream, YggRep.lastReservedDocType+1, YggRep.lastReservedDocType+1334]; theBytes _ NEW[YggRep.BitsRep[noBytes]]; theBytes.validBytes _ RandomChooseInt[randomStream, 1, noBytes]; FOR byteNo: CARD IN [0..theBytes.validBytes) DO theBytes.b[byteNo] _ RandomChooseInt[randomStream, 1, 255]; ENDLOOP; <> TRUSTED {tpe _ YggNav.ConstructUninterpretedBytesTPE[tpe.docType, LOOPHOLE[theBytes, LONG POINTER] + UNITS[YggRep.BitsRep[0]], noBytes];}; }; 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; contents: YggRep.TypedPrimitiveElement; vDocAttCount: INT _ 0; savedAttCount: INT _ 0; success: BOOL; parentDIDs: LIST OF YggDID.DID; YggVolatileObjectCache.InvalidateDID[did: lokd.first.did, transID: YggEnvironment.nullTransID]; IF YggVolatileObjectCache.LookupDIDInCache[did: lokd.first.did, transID: YggEnvironment.nullTransID, mode: read] # NIL THEN ERROR; YggDIDMap.FlushDocument[lokd.first.did, YggEnvironment.nullTransID]; trans _ YggNav.StartTransaction[YggEnvironment.nullTransID] ; 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]; IF lokd.first.contents.docType # YggNav.GetTypeOfContents[trans: YggEnvironment.nullTransID, did: lokd.first.did] THEN ERROR; [dids: parentDIDs, success: success] _ YggNav.GetParents[trans: trans, did: lokd.first.did, dontWait: TRUE]; FOR lop: LIST OF DID _ parentDIDs, lop.rest UNTIL lop = NIL DO FOR lodid: LIST OF DID _ lokd.first.containers, lodid.rest UNTIL lodid = NIL DO IF YggDID.EqualDIDs[lodid.first, lop.first] THEN EXIT; REPEAT FINISHED => ERROR; ENDLOOP; ENDLOOP; FOR lodid: LIST OF DID _ lokd.first.containers, lodid.rest UNTIL lodid = NIL DO IF lodid.first = NIL THEN { roots: LIST OF YggDID.DID; roots _ YggNav.GetRoots[]; FOR loroots: LIST OF DID _ roots, loroots.rest UNTIL loroots = NIL DO IF YggDID.EqualDIDs[loroots.first, lokd.first.did] THEN EXIT; REPEAT FINISHED => ERROR; ENDLOOP; }; ENDLOOP; SELECT lokd.first.contents.docType FROM YggRep.int, YggRep.rope, YggRep.shortRope, YggRep.float, YggRep.date, YggRep.did => { contents _ YggNav.GetContents[ trans: YggEnvironment.nullTransID, did: lokd.first.did]; CompareTPE[contents, lokd.first.contents]; }; YggRep.uninterpretedBytes => { bytesMoved: CARD _ 0; firstByte: CARD _ 0; lastByte: CARD _ 0; uBytes: REF YggRep.BitsRep; gBytes: REF YggRep.BitsRep; uBytes _ NARROW[lokd.first.contents.bits]; gBytes _ NEW[YggRep.BitsRep[uBytes.validBytes]]; IF uBytes.validBytes > 3 THEN { lastByte _ RandomChooseInt[randomStream, 1, MIN[16384, uBytes.validBytes - 1]]; firstByte _ RandomChooseInt[randomStream, 0, lastByte-1]; } ELSE {firstByte _ 0; lastByte _ uBytes.validBytes - 1;}; TRUSTED {bytesMoved _ YggNav.GetUninterpretedContents[ trans: YggEnvironment.nullTransID, did: lokd.first.did, firstByte: firstByte, byteCount: lastByte-firstByte+1, to: LOOPHOLE[gBytes, LONG POINTER] + UNITS[YggRep.BitsRep[0]]]; }; IF bytesMoved # (lastByte-firstByte+1) THEN ERROR; FOR index: CARD IN [0..bytesMoved) DO IF gBytes[index] # uBytes[index+firstByte] THEN ERROR; ENDLOOP; }; ENDCASE; 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 IF aL.first.attributeName # NIL THEN { IF Rope.Fetch[aL.first.attributeName, 0] = '$ THEN LOOP; }; vDocAttCount _ vDocAttCount + 1; ENDLOOP; IF vDocAttCount # savedAttCount THEN ERROR; { contents: YggRep.TypedPrimitiveElement; properties: LIST OF YggRep.Attribute; savedAttCount _ 0; contents _ YggNav.GetContents[trans: trans, did: lokd.first.did]; CompareTPE[contents, lokd.first.contents]; properties _ YggNav.GetAllProperties[trans: trans, did: lokd.first.did]; FOR aL: LIST OF YggRep.Attribute _ lokd.first.attributes, aL.rest UNTIL aL = NIL DO FOR aLVDoc: LIST OF YggRep.Attribute _ properties, 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; vDocAttCount _ 0; FOR aL: LIST OF YggRep.Attribute _ properties, aL.rest UNTIL aL = NIL DO IF aL.first.attributeName # NIL THEN { IF Rope.Fetch[aL.first.attributeName, 0] = '$ THEN LOOP; }; vDocAttCount _ vDocAttCount + 1; ENDLOOP; IF vDocAttCount # savedAttCount THEN ERROR; }; { linkList: LIST OF YggNav.LinkList; linkList _ YggNav.GetAllInlinks[trans: trans, did: lokd.first.did]; FOR ll: LIST OF YggNav.LinkList _ linkList, ll.rest UNTIL ll = NIL DO FOR didList: LIST OF YggDID.DID _ ll.first.dids, didList.rest UNTIL didList = NIL DO FOR inl: LIST OF linkStuff _ lokd.first.inlinks, inl.rest UNTIL inl = NIL DO IF Rope.Equal[ll.first.linkName, inl.first.linkType] AND YggDID.EqualDIDs[didList.first, inl.first.linkDID] THEN EXIT; REPEAT FINISHED => ERROR; ENDLOOP; ENDLOOP; ENDLOOP; }; IF ~YggNav.EndTransaction[trans, TRUE] THEN ERROR; }; argv: CommandTool.ArgumentVector; out: IO.STREAM; randomStream: Random.RandomStream; noisy: BOOL _ FALSE; fixedRandom: 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; DO IF Rope.InlineFetch[argv[offset+1], 0] = '- THEN { c: CHAR; IF argv[offset+1].Length[] # 2 THEN GOTO failed; c _ argv[offset+1].InlineFetch[1] ; SELECT c FROM 'n => noisy _ TRUE; 'f => fixedRandom _ TRUE; ENDCASE; offset _ offset + 1; } ELSE EXIT; ENDLOOP; noTests _ Convert.IntFromRope[argv[1+offset] ! Convert.Error => GOTO failed]; KnownDIDs _ NIL; NumberOfKnownDIDs _ 0; IF noTests <= 0 THEN RETURN; YggdrasilInit.InitializePart1[]; [] _ YggdrasilInit.InitializePart2["bogus", "pooz"]; randomStream _ Random.Create[range: 16384, seed: -1] ; FOR loopCount: INT IN (0..noTests] DO rand: INT _ RandomChooseInt[randomStream, 0, 40]; Process.CheckForAbort[]; IF noisy AND (loopCount MOD 100) = 0 THEN out.PutF["...(loopCount %g, number of DIDs %g at %g)...\n", IO.int[loopCount], IO.int[NumberOfKnownDIDs], IO.time[]]; IF loopCount = noTests THEN rand _ 0; SELECT rand FROM IN [0..1) => { -- volatalize and look up all old dids lokd: LIST OF DIDStuff; skipMax: INT _ 1; skipCnt: INT _ 0; IF NumberOfKnownDIDs <= 0 THEN LOOP; SELECT loopCount FROM IN [250..500) => skipMax _ RandomChooseInt[randomStream, 1, 3]; IN [500..1000) => skipMax _ RandomChooseInt[randomStream, 1, 7]; IN [1000..2000) => skipMax _ RandomChooseInt[randomStream, 1, 15]; IN [2000..4000) => skipMax _ RandomChooseInt[randomStream, 1, 33]; IN [4000..8000) => skipMax _ RandomChooseInt[randomStream, 1, 67]; IN [8000..16000) => skipMax _ RandomChooseInt[randomStream, 1, 155]; ENDCASE; IF loopCount = noTests THEN skipMax _ 1; IF noisy THEN out.PutF["\nStart Look Up All Old Dids, loopCount= %g, skipMax= %g\n", IO.int[loopCount], IO.int[skipMax]]; FOR lokd _ KnownDIDs, lokd.rest UNTIL lokd = NIL DO skipCnt _ skipCnt + 1; IF skipCnt >= skipMax THEN skipCnt _ 0 ELSE LOOP; CheckADID[lokd]; ENDLOOP; IF noisy THEN out.PutF["Look Up All Old Dids Done\n\n"]; }; IN [1..13) => { -- make new doc with a contents rand: INT; lokd: LIST OF DIDStuff; newDID: DID; containerDID: DID _ NIL; contents: YggRep.TypedPrimitiveElement; trans: YggTransaction.TransID; rand _ RandomChooseInt[randomStream, 0, MIN[16384, MAX[0, NumberOfKnownDIDs-2]]]; FOR lokd _ KnownDIDs, lokd.rest UNTIL lokd = NIL DO rand _ rand - 1; IF rand <= 0 THEN EXIT; ENDLOOP; IF lokd # NIL THEN containerDID _ lokd.first.did; trans _ YggNav.StartTransaction[YggEnvironment.nullTransID] ; newDID _ YggNav.CreateObject [trans: trans, containerDID: containerDID, makeRoot: IF lokd = NIL THEN TRUE ELSE FALSE] ; contents _ MakeUpTPE[]; KnownDIDs _ CONS[[did: newDID, contents: contents, containers: LIST[containerDID]], KnownDIDs]; NumberOfKnownDIDs _ NumberOfKnownDIDs + 1; YggNav.SetContents[trans: trans, did: newDID, contents: contents]; IF ~YggNav.EndTransaction[trans, TRUE] THEN ERROR; IF noisy THEN out.PutF["Make new doc: did= %g contents type= %g\n", IO.card[newDID.didLow], IO.card[contents.docType] ]; }; IN [13..19) => { -- volatalize and look up old did rand: INT; lokd: LIST OF DIDStuff; IF NumberOfKnownDIDs <= 0 THEN LOOP; rand _ RandomChooseInt[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 [19..28) => { -- 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]; IF NumberOfKnownDIDs <= 0 THEN LOOP; rand _ RandomChooseInt[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 _ YggNav.StartTransaction[YggEnvironment.nullTransID] ; FOR tryNo: INT IN [0..7] DO propertyNames: LIST OF ROPE; propExists: BOOL _ FALSE; rand _ RandomChooseInt[randomStream, 0, 8]; attrName _ attrNameArray[rand]; propertyNames _ YggNav.ListAllProperties[trans: trans, did: lokd.first.did]; FOR lor: LIST OF ROPE _ propertyNames, lor.rest UNTIL lor = NIL DO IF Rope.Equal[lor.first, attrName] THEN { propExists _ TRUE; EXIT; }; ENDLOOP; IF ~propExists THEN EXIT; attrName _ NIL; ENDLOOP; IF attrName = NIL THEN {IF ~YggNav.EndTransaction[trans, TRUE] THEN ERROR; LOOP;}; noAttrVals _ RandomChooseInt[randomStream, 1, 5]; property.value _ NIL; FOR attrValNo: INT IN [0..noAttrVals) DO attrVal: YggRep.AttributeValue; fni: INT; fni _ RandomChooseInt[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; YggNav.SetProperty[trans: trans, did: lokd.first.did, propertyName: attrName, property: property, appendProperty: TRUE]; lokd.first.attributes _ CONS[property, lokd.first.attributes]; IF ~YggNav.EndTransaction[trans, TRUE] THEN ERROR; IF noisy THEN out.PutF["add attribute to old did: did= %g\n", IO.card[lokd.first.did.didLow]]; }; IN [28..32) => { -- change contents rand: INT; contents: YggRep.TypedPrimitiveElement; trans: YggTransaction.TransID; lokd: LIST OF DIDStuff; IF NumberOfKnownDIDs <= 0 THEN LOOP; rand _ RandomChooseInt[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 _ YggNav.StartTransaction[YggEnvironment.nullTransID] ; SELECT lokd.first.contents.docType FROM YggRep.uninterpretedBytes => { newSize: CARD _ 0; bytesMoved: CARD _ 0; firstByte: CARD _ 0; lastByte: CARD _ 0; uBytes: REF YggRep.BitsRep; gBytes: REF YggRep.BitsRep; uBytes _ NARROW[lokd.first.contents.bits]; newSize _ RandomChooseInt[randomStream, 8+uBytes.validBytes/2, 8+3*uBytes.validBytes/2]; gBytes _ NEW[YggRep.BitsRep[newSize]]; gBytes.validBytes _ newSize; FOR byteNo: CARD IN [0..MIN[uBytes.validBytes, gBytes.validBytes]) DO gBytes.b[byteNo] _ uBytes.b[byteNo]; ENDLOOP; FOR byteNo: CARD IN [MIN[uBytes.validBytes, gBytes.validBytes]..newSize) DO gBytes.b[byteNo] _ RandomChooseInt[randomStream, 1, 255]; ENDLOOP; IF newSize <= uBytes.validBytes THEN YggNav.SetSize[trans: trans, did: lokd.first.did, size: newSize] ELSE { bytesMoved: CARD _ 0; roundDownFirstByte: CARD _ 0; roundDownFirstByte _ (uBytes.validBytes/2) * 2; TRUSTED {bytesMoved _ YggNav.SetUninterpretedContents[trans: trans, did: lokd.first.did, setDocType: FALSE, docType: YggRep.noValue, firstByte: roundDownFirstByte, byteCount: newSize-roundDownFirstByte, from: LOOPHOLE[gBytes, LONG POINTER] + UNITS[YggRep.BitsRep[roundDownFirstByte]]]; }; IF bytesMoved # (newSize - roundDownFirstByte) THEN ERROR; }; lokd.first.contents.bits _ gBytes; }; ENDCASE => { contents _ MakeUpTPE[]; lokd.first.contents _ contents; YggNav.SetContents[trans: trans, did: lokd.first.did, contents: contents]; }; IF lokd.first.contents.docType # YggNav.GetTypeOfContents[trans: trans, did: lokd.first.did] THEN ERROR; IF ~YggNav.EndTransaction[trans, TRUE] THEN ERROR; IF noisy THEN out.PutF["change contents of old did: did= %g, contents type= %g\n", IO.card[lokd.first.did.didLow], IO.card[lokd.first.contents.docType]]; }; IN [32..40) => { -- add a link inrand: INT; outrand: INT; ctr: INT _ 300; trans: YggTransaction.TransID; inlokd: LIST OF DIDStuff; outlokd: LIST OF DIDStuff; linkType: ROPE; linkDID: YggDID.DID; IF NumberOfKnownDIDs <= 0 THEN LOOP; inrand _ RandomChooseInt[randomStream, 0, MIN[16384, NumberOfKnownDIDs]]; outrand _ inrand; WHILE outrand = inrand AND ctr > 0 DO outrand _ RandomChooseInt[randomStream, 0, MIN[16384, NumberOfKnownDIDs]]; ctr _ ctr - 1; ENDLOOP; IF ctr <= 0 THEN LOOP; FOR inlokd _ KnownDIDs, inlokd.rest UNTIL inlokd = NIL DO inrand _ inrand - 1; IF inrand <= 0 THEN EXIT; ENDLOOP; IF inlokd = NIL THEN LOOP; FOR outlokd _ KnownDIDs, outlokd.rest UNTIL outlokd = NIL DO outrand _ outrand - 1; IF outrand <= 0 THEN EXIT; ENDLOOP; IF outlokd = NIL THEN LOOP; IF YggDID.EqualDIDs[outlokd.first.did, inlokd.first.did] THEN LOOP; linkType _ linkTypes[RandomChooseInt[randomStream, 0, 8]]; trans _ YggNav.StartTransaction[YggEnvironment.nullTransID] ; linkDID _ YggNav.SnapLink[trans: trans, fromDID: outlokd.first.did, toDID: inlokd.first.did, linkType: linkType]; IF ~YggNav.EndTransaction[trans, TRUE] THEN ERROR; outlokd.first.outlinks _ CONS[[linkType, linkDID, inlokd.first.did], outlokd.first.outlinks]; inlokd.first.inlinks _ CONS[[linkType, linkDID, outlokd.first.did], inlokd.first.inlinks]; IF noisy THEN out.PutF["add link from %g to %d, type= %g\n", IO.card[outlokd.first.did.didLow], IO.card[inlokd.first.did.didLow], IO.rope[linkType]]; }; ENDCASE; ENDLOOP; EXITS failed => {result _ $Failure}; }; <> Init: PROC = { Commander.Register["NavTest", NavTestProc, "NavTest noTests"]; }; Init[]; END. <<>>