/* Copyright (c) Microsoft Corporation. Licensed under the MIT License. */ /*************************************************************************** Author: ShonK Project: Kauai test app Reviewed: Copyright (c) Microsoft Corporation Test code used in both ut and ft. ***************************************************************************/ #include "util.h" ASSERTNAME #ifdef DEBUG extern void CheckForLostMem(BASE *po); #else //!DEBUG #define CheckForLostMem(po) #endif //!DEBUG void TestInt(void); void TestMem(void); void TestGl(void); void TestFni(void); void TestFil(void); void TestGg(void); void TestCfl(void); void TestErs(void); void TestCrf(void); /****************************************************************************** Test util code. ******************************************************************************/ void TestUtil(void) { Bug("Assert Test"); long lw = 0x12345678; BugVar("AssertVar test", &lw); TestInt(); TestMem(); TestErs(); TestGl(); TestGg(); //TestFni(); //TestFil(); //TestCfl(); TestCrf(); } /*************************************************************************** Test utilint stuff. ***************************************************************************/ void TestInt(void) { AssertDo(SwHigh(0x12345678) == (short)0x1234, 0); AssertDo(SwHigh(0xABCDEF01) == (short)0xABCD, 0); AssertDo(SwLow(0x12345678) == (short)0x5678, 0); AssertDo(SwLow(0xABCDEF01) == (short)0xEF01, 0); AssertDo(LwHighLow(0x1234, 0x5678) == 0x12345678, 0); AssertDo(LwHighLow((short)0xABCD, (short)0xEF01) == 0xABCDEF01, 0); AssertDo(BHigh(0x1234) == 0x12, 0); AssertDo(BHigh((short)0xABCD) == 0xAB, 0); AssertDo(BLow(0x1234) == 0x34, 0); AssertDo(BLow((short)0xABCD) == 0xCD, 0); AssertDo(SwHighLow(0x12, 0x56) == (short)0x1256, 0); AssertDo(SwHighLow(0xAB, 0xEF) == (short)0xABEF, 0); AssertDo(SwMin(kswMax, kswMin) == kswMin, 0); AssertDo(SwMin(kswMin, kswMax) == kswMin, 0); AssertDo(SwMax(kswMax, kswMin) == kswMax, 0); AssertDo(SwMax(kswMin, kswMax) == kswMax, 0); AssertDo(SuMin(ksuMax, 0) == 0, 0); AssertDo(SuMin(0, ksuMax) == 0, 0); AssertDo(SuMax(ksuMax, 0) == ksuMax, 0); AssertDo(SuMax(0, ksuMax) == ksuMax, 0); AssertDo(LwMin(klwMax, klwMin) == klwMin, 0); AssertDo(LwMin(klwMin, klwMax) == klwMin, 0); AssertDo(LwMax(klwMax, klwMin) == klwMax, 0); AssertDo(LwMax(klwMin, klwMax) == klwMax, 0); AssertDo(LuMin(kluMax, 0) == 0, 0); AssertDo(LuMin(0, kluMax) == 0, 0); AssertDo(LuMax(kluMax, 0) == kluMax, 0); AssertDo(LuMax(0, kluMax) == kluMax, 0); AssertDo(SwAbs(kswMax) == kswMax, 0); AssertDo(SwAbs(kswMin) == -kswMin, 0); AssertDo(LwAbs(klwMax) == klwMax, 0); AssertDo(LwAbs(klwMin) == -klwMin, 0); AssertDo(LwMulSw(kswMax, kswMax) == 0x3FFF0001, 0); AssertDo(LwMulSw(kswMin, kswMin) == 0x3FFF0001, 0); AssertDo(LwMulSw(kswMax, kswMin) == -0x3FFF0001, 0); AssertDo(LwMulDiv(klwMax, klwMax, klwMin) == klwMin, 0); AssertDo(LwMulDiv(klwMax, klwMin, klwMax) == klwMin, 0); AssertDo(CbRoundToLong(0) == 0, 0); AssertDo(CbRoundToLong(1) == 4, 0); AssertDo(CbRoundToLong(2) == 4, 0); AssertDo(CbRoundToLong(3) == 4, 0); AssertDo(CbRoundToLong(4) == 4, 0); AssertDo(CbRoundToLong(5) == 8, 0); AssertDo(CbRoundToShort(0) == 0, 0); AssertDo(CbRoundToShort(1) == 2, 0); AssertDo(CbRoundToShort(2) == 2, 0); AssertDo(CbRoundToShort(3) == 4, 0); AssertDo(CbRoundToShort(4) == 4, 0); AssertDo(CbRoundToShort(5) == 6, 0); AssertDo(LwGcd(10000, 350) == 50, 0); AssertDo(LwGcd(10000, -560) == 80, 0); AssertDo(FcmpCompareFracs(50000, 30000, 300000, 200000) == fcmpGt, 0); AssertDo(FcmpCompareFracs(-50000, 30000, -300000, 200000) == fcmpLt, 0); AssertDo(FcmpCompareFracs(-50000, 30000, 300000, 200000) == fcmpLt, 0); AssertDo(FcmpCompareFracs(50000, 30000, -300000, 200000) == fcmpGt, 0); AssertDo(FcmpCompareFracs(50000, 30000, 500000, 300000) == fcmpEq, 0); AssertDo(FcmpCompareFracs(0x1FFF0000, 0x10, 0x11000000, 0x10) == fcmpGt, 0); } /*************************************************************************** Test the memory manager. ***************************************************************************/ void TestMem(void) { #define kchq 18 static HQ rghq[kchq]; //static so it's initially zeros HQ hqT, hq; long cb, ihq; for (ihq = 0; ihq < kchq; ihq++) { cb = (1L << ihq) - 1 + ihq; if (!FAllocHq(&hq, cb, fmemNil, mprDebug)) { BugVar("HqAlloc failed on size:", &cb); break; } rghq[ihq] = hq; AssertDo(CbOfHq(hq) == cb, 0); FillPb(QvFromHq(hq), cb, (byte)cb); if (cb > 0) { AssertDo(*(byte *)QvFromHq(hq) == (byte)cb, 0); AssertDo(*(byte *)PvAddBv(QvFromHq(hq), cb - 1) == (byte)cb, 0); } AssertDo(PvLockHq(hq) == QvFromHq(hq), 0); if (!FCopyHq(hq, &hqT, mprDebug)) Bug("FCopyHq failed"); else { AssertDo(CbOfHq(hqT) == cb, 0); if (cb > 0) { AssertDo(*(byte *)QvFromHq(hqT) == (byte)cb, 0); AssertDo(*(byte *)PvAddBv(QvFromHq(hqT), cb - 1) == (byte)cb, 0); } FreePhq(&hqT); } Assert(hqT == hqNil, 0); FreePhq(&hqT); UnlockHq(hq); } for (ihq = 0; ihq < kchq; ihq++) { hq = rghq[ihq]; if (hqNil == hq) break; cb = CbOfHq(hq); if (!FResizePhq(&rghq[ihq], 2 * cb, fmemClear, mprDebug)) { Bug("FResizePhq failed"); break; } hq = rghq[ihq]; if (cb > 0) { AssertDo(*(byte *)QvFromHq(hq) == (byte)cb, 0); AssertDo(*(byte *)PvAddBv(QvFromHq(hq), cb - 1) == (byte)cb, 0); AssertDo(*(byte *)PvAddBv(QvFromHq(hq), cb) == 0, 0); AssertDo(*(byte *)PvAddBv(QvFromHq(hq), 2 * cb - 1) == 0, 0); } } for (ihq = 0; ihq < kchq; ihq++) { if (hqNil != rghq[ihq]) { cb = (1L << (kchq - 1 - ihq)) - 1 + (kchq - 1 - ihq); AssertDo(FResizePhq(&rghq[ihq], cb, fmemNil, mprDebug), "FResizePhq failed"); } FreePhq(&rghq[ihq]); } } /*************************************************************************** Test list code. ***************************************************************************/ void TestGl(void) { short sw; long isw; short *qsw; PGL pglsw; pglsw = GL::PglNew(size(short)); if (pvNil == pglsw) { Bug("PglNew failed"); return; } for (sw = 0; sw < 10; sw++) { AssertDo(pglsw->FAdd(&sw, &isw), 0); AssertDo(isw == sw, 0); } AssertDo(pglsw->IvMac() == 10, 0); for (isw = 0; isw < 10; isw++) { qsw = (short *)pglsw->QvGet(isw); AssertDo(*qsw == isw, 0); pglsw->Get(isw, &sw); AssertDo(sw == isw, 0); } for (isw = 10; isw > 0; ) pglsw->Delete(isw -= 2); AssertDo(pglsw->IvMac() == 5, 0); for (isw = 0; isw < 5; isw++) { pglsw->Get(isw, &sw); AssertDo(sw == isw * 2 + 1, 0); sw = (short)isw * 100; pglsw->Put(isw, &sw); qsw = (short *)pglsw->QvGet(isw); AssertDo(*qsw == isw * 100, 0); *qsw = (short)isw; } AssertDo(pglsw->IvMac() == 5, 0); AssertDo(pglsw->FEnsureSpace(0, fgrpShrink), 0); AssertDo(pglsw->IvMac() == 5, 0); for (isw = 5; isw-- != 0; ) { sw = (short)isw; pglsw->FInsert(isw, &sw); } AssertDo(pglsw->IvMac() == 10, 0); for (isw = 10; isw-- != 0; ) { pglsw->Get(isw, &sw); AssertDo(sw == isw / 2, 0); } ReleasePpo(&pglsw); } /*************************************************************************** Test the fni code. ***************************************************************************/ void TestFni(void) { FNI fni1, fni2; STN stn1, stn2, stn3; AssertDo(fni1.FGetTemp(), 0); AssertDo(fni1.Ftg() == vftgTemp, 0); AssertDo(!fni1.FDir(), 0); fni2 = fni1; fni1.GetLeaf(&stn3); fni2.GetLeaf(&stn2); AssertDo(stn3.FEqual(&stn2), 0); AssertDo(fni1.FSetLeaf(pvNil, kftgDir), 0); AssertDo(fni1.FDir(), 0); AssertDo(fni1.Ftg() == kftgDir, 0); AssertDo(fni1.FUpDir(&stn1, ffniNil), 0); AssertDo(fni1.FUpDir(&stn2, ffniMoveToDir), 0); AssertDo(stn1.FEqual(&stn2), 0); AssertDo(!fni1.FSameDir(&fni2), 0); AssertDo(!fni1.FEqual(&fni2), 0); AssertDo(fni1.Ftg() == kftgDir, 0); AssertDo(fni1.FDownDir(&stn1, ffniNil), 0); AssertDo(!fni1.FSameDir(&fni2), 0); AssertDo(fni1.FDownDir(&stn1, ffniMoveToDir), 0); AssertDo(fni1.FSameDir(&fni2), 0); AssertDo(fni1.FSetLeaf(&stn3, vftgTemp), 0); AssertDo(fni1.FEqual(&fni2), 0); AssertDo(fni1.TExists() == tNo, 0); AssertDo(fni2.FSetLeaf(pvNil, kftgDir), 0); AssertDo(fni2.FGetUnique(vftgTemp), 0); AssertDo(!fni1.FEqual(&fni2), 0); } /*************************************************************************** File test code. ***************************************************************************/ void TestFil(void) { PFIL pfil; FNI fni; while (FGetFniSaveMacro(&fni, 'TEXT', "\x9" "Save As: ", "\x4" "Junk", PszLit("All files\0*.*\0"), NULL)) { AssertDo(fni.TExists() == tNo, 0); pfil = FIL::PfilCreate(&fni); AssertPo(pfil, 0); AssertDo(pfil->FSetFpMac(100), 0); AssertDo(pfil->FpMac() == 100, 0); AssertDo(pfil->FWriteRgb(&fni, size(fni), 0), 0); pfil->SetTemp(fTrue); pfil->Mark(); ReleasePpo(&pfil); } FIL::CloseUnmarked(); FIL::ClearMarks(); FIL::CloseUnmarked(); } /*************************************************************************** Test the group api. ***************************************************************************/ void TestGg(void) { PGG pgg; ulong grf; long cb, iv; byte *qb; PSZ psz = PszLit("0123456789ABCDEFG"); achar rgch[100]; AssertDo((pgg = GG::PggNew(0)) != pvNil, 0); for (iv = 0; iv < 10; iv++) { AssertDo(pgg->FInsert(iv / 2, iv + 1, psz), 0); } AssertDo(pgg->FAdd(16, &iv, psz), 0); AssertDo(iv == 10, 0); AssertDo(pgg->IvMac() == 11, 0); grf = 0; for (iv = pgg->IvMac(); iv--; ) { cb = pgg->Cb(iv); qb = (byte *)pgg->QvGet(iv); AssertDo(FEqualRgb(psz, qb, cb), 0); grf |= 1L << cb; if (cb & 1) pgg->Delete(iv); } AssertDo(grf == 0x000107FE, 0); grf = 0; for (iv = pgg->IvMac(); iv--; ) { cb = pgg->Cb(iv); AssertDo(!(cb & 1), 0); pgg->Get(iv, rgch); qb = (byte *)pgg->QvGet(iv); AssertDo(FEqualRgb(rgch, qb, cb), 0); AssertDo(FEqualRgb(rgch, psz, cb), 0); grf |= 1L << cb; CopyPb(psz, rgch + cb, cb); AssertDo(pgg->FPut(iv, cb + cb, rgch), 0); } AssertDo(grf == 0x00010554, 0); grf = 0; for (iv = pgg->IvMac(); iv--; ) { cb = pgg->Cb(iv); AssertDo(!(cb & 3), 0); cb /= 2; grf |= 1L << cb; pgg->DeleteRgb(iv, LwMin(cb, iv), cb); qb = (byte *)pgg->QvGet(iv); AssertDo(FEqualRgb(psz, qb, cb), 0); } AssertDo(grf == 0x00010554, 0); ReleasePpo(&pgg); } /*************************************************************************** Test the chunky file stuff. ***************************************************************************/ void TestCfl(void) { enum { relPaul, relMarge, relTig, relCarl, relPriscilla, relGreg, relShon, relClaire, relMike, relStephen, relBaby, relCathy, relJoshua, relRachel, relLim }; struct EREL { CTG ctg; CNO cno; PSZ psz; short relPar1, relPar2; }; const CTG kctgLan = 0x41414141; const CTG kctgKatz = 0x42424242; const CTG kctgSandy = 0x43434343; EREL dnrel[relLim] = { { kctgLan, 0, PszLit("Paul"), relLim, relLim }, { kctgLan, 0, PszLit("Marge"), relLim, relLim }, { kctgLan, 0, PszLit("Tig"), relPaul, relMarge }, { kctgKatz, 0, PszLit("Carl"), relLim, relLim }, { kctgKatz, 0, PszLit("Priscilla"), relLim, relLim }, { kctgKatz, 0, PszLit("Greg"), relCarl, relPriscilla }, { kctgKatz, 0, PszLit("Shon"), relCarl, relPriscilla }, { kctgKatz, 0, PszLit("Claire"), relPaul, relMarge }, { kctgKatz, 0, PszLit("Mike"), relCarl, relPriscilla }, { kctgKatz, 0, PszLit("Stephen"), relGreg, relLim }, { kctgKatz, 0, PszLit("Baby"), relShon, relClaire }, { kctgSandy, 0, PszLit("Cathy"), relCarl, relPriscilla }, { kctgSandy, 0, PszLit("Joshua"), relCathy, relLim }, { kctgSandy, 0, PszLit("Rachel"), relCathy, relLim }, }; FNI fni, fniDst; PCFL pcfl, pcflDst; BLCK blck; short rel; long icki; CNO cno; CKI cki; EREL *perel, *perelPar; STN stn; achar rgch[kcchMaxSz]; while (FGetFniSaveMacro(&fni, 'TEXT', "\x9" "Save As: ", "\x4" "Junk", PszLit("All files\0*.*\0"), NULL)) { AssertDo((pcfl = CFL::PcflCreate(&fni, fcflNil)) != pvNil, 0); AssertDo(fniDst.FGetTemp(), 0); AssertDo((pcflDst = CFL::PcflCreate(&fniDst, fcflNil)) != pvNil, 0); for (rel = 0; rel < relLim; rel++) { perel = &dnrel[rel]; AssertDo(pcfl->FAddPv(perel->psz, CchSz(perel->psz), perel->ctg, &perel->cno), 0); stn = perel->psz; AssertDo(pcfl->FSetName(perel->ctg, perel->cno, &stn), 0); if (perel->relPar1 < relLim) { perelPar = &dnrel[perel->relPar1]; AssertDo(pcfl->FAdoptChild(perelPar->ctg, perelPar->cno, perel->ctg, perel->cno), 0); } if (perel->relPar2 < relLim) { perelPar = &dnrel[perel->relPar2]; AssertDo(pcfl->FAdoptChild(perelPar->ctg, perelPar->cno, perel->ctg, perel->cno), 0); } AssertDo(pcfl->FCopy(perel->ctg, perel->cno, pcflDst, &cno), "copy failed"); } AssertDo(pcfl->Ccki() == 14, 0); for (rel = 0; rel < relLim; rel++) { perel = &dnrel[rel]; pcfl->FGetName(perel->ctg, perel->cno, &stn); AssertDo(FEqualRgb(stn.Prgch(), perel->psz, stn.Cch()), 0); AssertDo(pcfl->FFind(perel->ctg, perel->cno, &blck), 0); AssertDo(blck.FRead(rgch), 0); AssertDo(FEqualRgb(rgch, perel->psz, CchSz(perel->psz) * size(achar)), 0); } // copy all the chunks - they should already be there, but this // should set up all the child links for (rel = 0; rel < relLim; rel++) { perel = &dnrel[rel]; AssertDo(pcfl->FCopy(perel->ctg, perel->cno, pcflDst, &cno), "copy failed"); } AssertPo(pcflDst, fcflFull); // this should delete relShon, but not relBaby perelPar = &dnrel[relCarl]; perel = &dnrel[relShon]; pcfl->DeleteChild(perelPar->ctg, perelPar->cno, perel->ctg, perel->cno); perelPar = &dnrel[relPriscilla]; pcfl->DeleteChild(perelPar->ctg, perelPar->cno, perel->ctg, perel->cno); AssertDo(pcfl->Ccki() == 13, 0); // this should delete relGreg and relStephen perelPar = &dnrel[relCarl]; perel = &dnrel[relGreg]; pcfl->DeleteChild(perelPar->ctg, perelPar->cno, perel->ctg, perel->cno); perelPar = &dnrel[relPriscilla]; pcfl->DeleteChild(perelPar->ctg, perelPar->cno, perel->ctg, perel->cno); AssertDo(pcfl->Ccki() == 11, 0); // this should delete relCarl, relPriscilla, relCathy, relJoshua, // relRachel and relMike pcfl->Delete(perelPar->ctg, perelPar->cno); perelPar = &dnrel[relCarl]; pcfl->Delete(perelPar->ctg, perelPar->cno); AssertDo(pcfl->Ccki() == 5, 0); for (icki = 0; pcfl->FGetCki(icki, &cki); icki++) { AssertDo(pcfl->FGetName(cki.ctg, cki.cno, &stn), 0); AssertDo(pcfl->FFind(cki.ctg, cki.cno, &blck), 0); AssertDo(blck.FRead(rgch), 0); AssertDo(FEqualRgb(rgch, stn.Prgch(), stn.Cch() * size(achar)), 0); AssertDo(stn.Cch() * size(achar) == blck.Cb(), 0); } // copy all the chunks back for (icki = 0; pcflDst->FGetCki(icki, &cki); icki++) { AssertDo(pcflDst->FCopy(cki.ctg, cki.cno, pcfl, &cno), "copy failed"); } AssertPo(pcfl, fcflFull); AssertDo(pcfl->Ccki() == 14, 0); ReleasePpo(&pcflDst); AssertDo(pcfl->FSave(BigLittle('JUNK', 'KNUJ'), pvNil), 0); ReleasePpo(&pcfl); } while (FGetFniOpenMacro(&fni, pvNil, 0, PszLit("All files\0*.*\0"), NULL)) { AssertDo(fni.TExists() == tYes, 0); pcfl = CFL::PcflOpen(&fni, fcflNil); if (pcfl == pvNil) continue; AssertPo(pcfl, 0); if (FGetFniSaveMacro(&fni, 'TEXT', "\x9" "Save As: ", "\x4" "Junk", PszLit("All files\0*.*\0"), NULL)) { AssertDo(pcfl->FSave(BigLittle('JUNK', 'KNUJ'), &fni), 0); } ReleasePpo(&pcfl); } CFL::CloseUnmarked(); CFL::ClearMarks(); CFL::CloseUnmarked(); } /****************************************************************************** Test the error registration code. ******************************************************************************/ void TestErs(void) { const long cercTest = 30; long erc, ercT; vpers->Clear(); Assert(vpers->Cerc() == 0, "bad count of error codes on stack"); for (erc = 0; erc < cercTest; erc++) { Assert(vpers->Cerc() == LwMin(erc, kcerdMax), "bad count of error codes on stack"); PushErc(erc); AssertVar(vpers->FIn(erc), "error code not found", &erc); } for (erc = cercTest - 1; vpers->FIn(erc); erc--) ; AssertVar(erc == cercTest - kcerdMax - 1, "lost error code", &erc); for (erc = 0; erc < vpers->Cerc(); erc++) { AssertVar((ercT = vpers->ErcGet(erc)) == cercTest - kcerdMax + erc, "invalid error code", &ercT); } for (erc = cercTest - 1; vpers->FPop(&ercT); erc--) AssertVar(ercT == erc, "bogus error code returned", &ercT); AssertVar(erc == cercTest - kcerdMax - 1, "lost error code", &erc); for (erc = 0; erc < cercTest; erc++) { Assert(vpers->Cerc() == LwMin(erc, kcerdMax), "bad count of error codes on stack"); PushErc(erc); AssertVar(vpers->FIn(erc), "error code not found", &erc); } vpers->Clear(); Assert(vpers->Cerc() == 0, "bad count of error codes on stack"); } /****************************************************************************** Test chunky resource file ******************************************************************************/ void TestCrf(void) { const CNO cnoLim = 10; FNI fni; CTG ctg = 'JUNK'; CNO cno; PGHQ rgpghq[cnoLim]; PCFL pcfl; PCRF pcrf; HQ hq; PGHQ pghq; if (!fni.FGetTemp() || pvNil == (pcfl = CFL::PcflCreate(&fni, fcflWriteEnable | fcflTemp))) { Bug("creating chunky file failed"); return; } for (cno = 0; cno < cnoLim; cno++) { AssertDo(pcfl->FPutPv("Test string", 11, ctg, cno), 0); } if (pvNil == (pcrf = CRF::PcrfNew(pcfl, 50))) { Bug("creating CRF failed"); ReleasePpo(&pcfl); return; } ReleasePpo(&pcfl); for (cno = 0; cno < cnoLim; cno++) pcrf->TLoad(ctg, cno, GHQ::FReadGhq, rscNil, 10); for (cno = 0; cno < cnoLim; cno++) pcrf->TLoad(ctg, cno, GHQ::FReadGhq, rscNil, 20); for (cno = 0; cno < cnoLim; cno++) pcrf->TLoad(ctg, cno, GHQ::FReadGhq, rscNil, 20 + cno); for (cno = 0; cno < cnoLim; cno++) { pghq = (PGHQ)pcrf->PbacoFetch(ctg, cno, GHQ::FReadGhq); if (pvNil == pghq) continue; hq = pghq->hq; Assert(CbOfHq(hq) == 11, "wrong length"); Assert(FEqualRgb(QvFromHq(hq), "Test string", 11), "bad bytes"); ReleasePpo(&pghq); } for (cno = 0; cno < cnoLim; cno++) { pghq = (PGHQ)pcrf->PbacoFetch(ctg, cno, GHQ::FReadGhq); rgpghq[cno] = pghq; if (pvNil == pghq) continue; hq = pghq->hq; Assert(CbOfHq(hq) == 11, "wrong length"); Assert(FEqualRgb(QvFromHq(hq), "Test string", 11), "bad bytes"); } for (cno = 0; cno < cnoLim; cno++) { ReleasePpo(&rgpghq[cno]); } ReleasePpo(&pcrf); }