diff options
Diffstat (limited to 'indra/newview/tests')
23 files changed, 10518 insertions, 54 deletions
diff --git a/indra/newview/tests/gpus_results.txt b/indra/newview/tests/gpus_results.txt new file mode 100644 index 0000000000..7e9a064921 --- /dev/null +++ b/indra/newview/tests/gpus_results.txt @@ -0,0 +1,1595 @@ +GPU String Supported? Class Recognizer +------------------------------------------------------------------------------------------------------ ----------- ----- ------------------------------------ +ATI UNRECOGNIZED +ATI 3D-Analyze unsupported 0 ATI 3D-Analyze +ATI ASUS A9xxx supported 1 ATI ASUS A9xxx +ATI ASUS AH24xx supported 1 ATI ASUS AH24xx +ATI ASUS AH26xx supported 3 ATI ASUS AH26xx +ATI ASUS AH34xx supported 1 ATI ASUS AH34xx +ATI ASUS AH36xx supported 3 ATI ASUS AH36xx +ATI ASUS AH46xx supported 3 ATI ASUS AH46xx +ATI ASUS AX3xx supported 1 ATI ASUS AX3xx +ATI ASUS AX5xx supported 1 ATI ASUS AX5xx +ATI ASUS AX8xx supported 2 ATI ASUS AX8xx +ATI ASUS EAH38xx supported 3 ATI ASUS EAH38xx +ATI ASUS EAH43xx supported 1 ATI ASUS EAH43xx +ATI ASUS EAH45xx supported 1 ATI ASUS EAH45xx +ATI ASUS EAH48xx supported 3 ATI ASUS EAH48xx +ATI ASUS EAH57xx supported 3 ATI ASUS EAH57xx +ATI ASUS EAH58xx supported 3 ATI ASUS EAH58xx +ATI ASUS X1xxx supported 3 ATI ASUS Radeon X1xxx +ATI All-in-Wonder 9xxx supported 1 ATI All-in-Wonder 9xxx +ATI All-in-Wonder HD supported 1 ATI All-in-Wonder HD +ATI All-in-Wonder PCI-E supported 1 ATI All-in-Wonder PCI-E +ATI All-in-Wonder X1800 supported 3 ATI All-in-Wonder X1800 +ATI All-in-Wonder X1900 supported 3 ATI All-in-Wonder X1900 +ATI All-in-Wonder X600 supported 1 ATI All-in-Wonder X600 +ATI All-in-Wonder X800 supported 2 ATI All-in-Wonder X800 +ATI Diamond X1xxx supported 0 ATI Radeon X1xxx +ATI Display Adapter UNRECOGNIZED +ATI FireGL supported 0 ATI FireGL +ATI FireGL 5200 supported 0 ATI FireGL +ATI FireGL 5xxx supported 0 ATI FireGL +ATI FireMV supported 0 ATI FireMV +ATI Generic unsupported 0 ATI Generic +ATI Hercules 9800 supported 1 ATI Hercules 9800 +ATI IGP 340M unsupported 0 ATI IGP 340M +ATI M52 supported 1 ATI M52 +ATI M54 supported 1 ATI M54 +ATI M56 supported 1 ATI M56 +ATI M71 supported 1 ATI M71 +ATI M72 supported 1 ATI M72 +ATI M76 supported 3 ATI M76 +ATI Mobility Radeon supported 0 ATI Mobility Radeon +ATI Mobility Radeon 7xxx supported 0 ATI Mobility Radeon 7xxx +ATI Mobility Radeon 9600 supported 0 ATI Mobility Radeon 9600 +ATI Mobility Radeon 9700 supported 1 ATI Mobility Radeon 9700 +ATI Mobility Radeon 9800 supported 1 ATI Mobility Radeon 9800 +ATI Mobility Radeon HD 2300 supported 1 ATI Mobility Radeon HD 2300 +ATI Mobility Radeon HD 2400 supported 1 ATI Mobility Radeon HD 2400 +ATI Mobility Radeon HD 2600 supported 3 ATI Mobility Radeon HD 2600 +ATI Mobility Radeon HD 2700 supported 3 ATI Mobility Radeon HD 2700 +ATI Mobility Radeon HD 3400 supported 2 ATI Mobility Radeon HD 3400 +ATI Mobility Radeon HD 3600 supported 3 ATI Mobility Radeon HD 3600 +ATI Mobility Radeon HD 3800 supported 3 ATI Mobility Radeon HD 3800 +ATI Mobility Radeon HD 4200 supported 2 ATI Mobility Radeon HD 4200 +ATI Mobility Radeon HD 4300 supported 2 ATI Mobility Radeon HD 4300 +ATI Mobility Radeon HD 4500 supported 3 ATI Mobility Radeon HD 4500 +ATI Mobility Radeon HD 4600 supported 3 ATI Mobility Radeon HD 4600 +ATI Mobility Radeon HD 4800 supported 3 ATI Mobility Radeon HD 4800 +ATI Mobility Radeon HD 5400 supported 2 ATI Mobility Radeon HD 5400 +ATI Mobility Radeon HD 5600 supported 2 ATI Mobility Radeon HD 5600 +ATI Mobility Radeon X1xxx supported 0 ATI Radeon X1xxx +ATI Mobility Radeon X2xxx supported 0 ATI Mobility Radeon X2xxx +ATI Mobility Radeon X3xx supported 1 ATI Mobility Radeon X3xx +ATI Mobility Radeon X6xx supported 1 ATI Mobility Radeon X6xx +ATI Mobility Radeon X7xx supported 1 ATI Mobility Radeon X7xx +ATI Mobility Radeon Xxxx supported 0 ATI Mobility Radeon Xxxx +ATI RV380 supported 0 ATI RV380 +ATI RV530 supported 1 ATI RV530 +ATI Radeon 2100 supported 0 ATI Radeon 2100 +ATI Radeon 3000 supported 0 ATI Radeon 3000 +ATI Radeon 3100 supported 1 ATI Radeon 3100 +ATI Radeon 7000 supported 0 ATI Radeon 7xxx +ATI Radeon 7xxx supported 0 ATI Radeon 7xxx +ATI Radeon 8xxx supported 0 ATI Radeon 8xxx +ATI Radeon 9000 supported 0 ATI Radeon 9000 +ATI Radeon 9100 supported 0 ATI Radeon 9100 +ATI Radeon 9200 supported 0 ATI Radeon 9200 +ATI Radeon 9500 supported 0 ATI Radeon 9500 +ATI Radeon 9600 supported 0 ATI Radeon 9600 +ATI Radeon 9700 supported 1 ATI Radeon 9700 +ATI Radeon 9800 supported 1 ATI Radeon 9800 +ATI Radeon HD 2300 supported 0 ATI Radeon HD 2300 +ATI Radeon HD 2400 supported 1 ATI Radeon HD 2400 +ATI Radeon HD 2600 supported 2 ATI Radeon HD 2600 +ATI Radeon HD 2900 supported 3 ATI Radeon HD 2900 +ATI Radeon HD 3000 supported 0 ATI Radeon HD 3000 +ATI Radeon HD 3100 supported 1 ATI Radeon HD 3100 +ATI Radeon HD 3200 supported 0 ATI Radeon HD 3200 +ATI Radeon HD 3300 supported 1 ATI Radeon HD 3300 +ATI Radeon HD 3400 supported 1 ATI Radeon HD 3400 +ATI Radeon HD 3600 supported 3 ATI Radeon HD 3600 +ATI Radeon HD 3800 supported 3 ATI Radeon HD 3800 +ATI Radeon HD 4200 supported 1 ATI Radeon HD 4200 +ATI Radeon HD 4300 supported 1 ATI Radeon HD 4300 +ATI Radeon HD 4500 supported 3 ATI Radeon HD 4500 +ATI Radeon HD 4600 supported 3 ATI Radeon HD 4600 +ATI Radeon HD 4700 supported 3 ATI Radeon HD 4700 +ATI Radeon HD 4800 supported 3 ATI Radeon HD 4800 +ATI Radeon HD 5400 supported 3 ATI Radeon HD 5400 +ATI Radeon HD 5500 supported 3 ATI Radeon HD 5500 +ATI Radeon HD 5600 supported 3 ATI Radeon HD 5600 +ATI Radeon HD 5700 supported 3 ATI Radeon HD 5700 +ATI Radeon HD 5800 supported 3 ATI Radeon HD 5800 +ATI Radeon HD 5900 supported 3 ATI Radeon HD 5900 +ATI Radeon HD 6200 supported 2 ATI Radeon HD 6200 +ATI Radeon HD 6300 supported 2 ATI Radeon HD 6300 +ATI Radeon HD 6500 supported 3 ATI Radeon HD 6500 +ATI Radeon HD 6800 supported 3 ATI Radeon HD 6800 +ATI Radeon HD 6900 supported 3 ATI Radeon HD 6900 +ATI Radeon OpenGL supported 0 ATI Radeon +ATI Radeon RV250 supported 0 ATI Radeon RV250 +ATI Radeon RV600 supported 1 ATI Radeon RV600 +ATI Radeon RX9550 supported 1 ATI Radeon RX9550 +ATI Radeon VE unsupported 0 ATI Radeon VE +ATI Radeon X1000 supported 0 ATI Radeon X1xxx +ATI Radeon X1200 supported 0 ATI Radeon X1xxx +ATI Radeon X1300 supported 0 ATI Radeon X1xxx +ATI Radeon X13xx supported 0 ATI Radeon X1xxx +ATI Radeon X1400 supported 0 ATI Radeon X1xxx +ATI Radeon X1500 supported 0 ATI Radeon X1xxx +ATI Radeon X1600 supported 0 ATI Radeon X1xxx +ATI Radeon X16xx supported 0 ATI Radeon X1xxx +ATI Radeon X1700 supported 0 ATI Radeon X1xxx +ATI Radeon X1800 supported 0 ATI Radeon X1xxx +ATI Radeon X1900 supported 0 ATI Radeon X1xxx +ATI Radeon X19xx supported 0 ATI Radeon X1xxx +ATI Radeon X1xxx supported 0 ATI Radeon X1xxx +ATI Radeon X300 supported 0 ATI Radeon X300 +ATI Radeon X500 supported 0 ATI Radeon X500 +ATI Radeon X600 supported 1 ATI Radeon X600 +ATI Radeon X700 supported 1 ATI Radeon X700 +ATI Radeon X7xx supported 1 ATI Radeon X700 +ATI Radeon X800 supported 2 ATI Radeon X800 +ATI Radeon Xpress supported 0 ATI Radeon Xpress +ATI Rage 128 supported 0 ATI Rage 128 +ATI Technologies Inc. supported 0 ATI Technologies +ATI Technologies Inc. x86 supported 0 ATI Technologies +ATI Technologies Inc. x86/SSE2 supported 0 ATI Technologies +ATI Technologies Inc. (Vista) ATI Mobility Radeon HD 5730 supported 3 ATI Mobility Radeon HD 5700 +ATI Technologies Inc. 256MB ATI Radeon X1300PRO x86/SSE2 supported 0 ATI Radeon X1xxx +ATI Technologies Inc. AMD 760G supported 1 ATI 760G/Radeon 3000 +ATI Technologies Inc. AMD 760G (Microsoft WDDM 1.1) supported 1 ATI 760G/Radeon 3000 +ATI Technologies Inc. AMD 780L supported 1 ATI 780L/Radeon 3000 +ATI Technologies Inc. AMD FirePro 2270 supported 1 ATI FirePro 2000 +ATI Technologies Inc. AMD M860G with ATI Mobility Radeon 4100 supported 0 ATI Mobility Radeon 4100 +ATI Technologies Inc. AMD M880G with ATI Mobility Radeon HD 4200 supported 2 ATI Mobility Radeon HD 4200 +ATI Technologies Inc. AMD M880G with ATI Mobility Radeon HD 4250 supported 2 ATI Mobility Radeon HD 4200 +ATI Technologies Inc. AMD RADEON HD 6450 supported 3 ATI Radeon HD 6400 +ATI Technologies Inc. AMD Radeon HD 6200 series Graphics supported 2 ATI Radeon HD 6200 +ATI Technologies Inc. AMD Radeon HD 6250 Graphics supported 2 ATI Radeon HD 6200 +ATI Technologies Inc. AMD Radeon HD 6300 series Graphics supported 2 ATI Radeon HD 6300 +ATI Technologies Inc. AMD Radeon HD 6300M Series supported 2 ATI Radeon HD 6300 +ATI Technologies Inc. AMD Radeon HD 6310 Graphics supported 2 ATI Radeon HD 6300 +ATI Technologies Inc. AMD Radeon HD 6310M supported 2 ATI Radeon HD 6300 +ATI Technologies Inc. AMD Radeon HD 6330M supported 2 ATI Radeon HD 6300 +ATI Technologies Inc. AMD Radeon HD 6350 supported 2 ATI Radeon HD 6300 +ATI Technologies Inc. AMD Radeon HD 6370M supported 2 ATI Radeon HD 6300 +ATI Technologies Inc. AMD Radeon HD 6400M Series supported 3 ATI Radeon HD 6400 +ATI Technologies Inc. AMD Radeon HD 6450 supported 3 ATI Radeon HD 6400 +ATI Technologies Inc. AMD Radeon HD 6470M supported 3 ATI Radeon HD 6400 +ATI Technologies Inc. AMD Radeon HD 6490M supported 3 ATI Radeon HD 6400 +ATI Technologies Inc. AMD Radeon HD 6500M/5600/5700 Series supported 3 ATI Radeon HD 6500 +ATI Technologies Inc. AMD Radeon HD 6530M supported 3 ATI Radeon HD 6500 +ATI Technologies Inc. AMD Radeon HD 6550M supported 3 ATI Radeon HD 6500 +ATI Technologies Inc. AMD Radeon HD 6570 supported 3 ATI Radeon HD 6500 +ATI Technologies Inc. AMD Radeon HD 6570M supported 3 ATI Radeon HD 6500 +ATI Technologies Inc. AMD Radeon HD 6570M/5700 Series supported 3 ATI Radeon HD 6500 +ATI Technologies Inc. AMD Radeon HD 6600M Series supported 3 ATI Radeon HD 66xx +ATI Technologies Inc. AMD Radeon HD 6650M supported 3 ATI Radeon HD 66xx +ATI Technologies Inc. AMD Radeon HD 6670 supported 3 ATI Radeon HD 66xx +ATI Technologies Inc. AMD Radeon HD 6700 Series supported 3 ATI Radeon HD 6700 +ATI Technologies Inc. AMD Radeon HD 6750 supported 3 ATI Radeon HD 6700 +ATI Technologies Inc. AMD Radeon HD 6750M supported 3 ATI Radeon HD 6700 +ATI Technologies Inc. AMD Radeon HD 6770 supported 3 ATI Radeon HD 6700 +ATI Technologies Inc. AMD Radeon HD 6800 Series supported 3 ATI Radeon HD 6800 +ATI Technologies Inc. AMD Radeon HD 6850M supported 3 ATI Radeon HD 6800 +ATI Technologies Inc. AMD Radeon HD 6870 supported 3 ATI Radeon HD 6800 +ATI Technologies Inc. AMD Radeon HD 6870M supported 3 ATI Radeon HD 6800 +ATI Technologies Inc. AMD Radeon HD 6900 Series supported 3 ATI Radeon HD 6900 +ATI Technologies Inc. AMD Radeon HD 6970M supported 3 ATI Radeon HD 6900 +ATI Technologies Inc. AMD Radeon HD 6990 supported 3 ATI Radeon HD 6900 +ATI Technologies Inc. AMD Radeon(TM) HD 6470M supported 0 ATI Technologies +ATI Technologies Inc. ASUS 5870 Eyefinity 6 supported 0 ATI Technologies +ATI Technologies Inc. ASUS AH2600 Series supported 3 ATI ASUS AH26xx +ATI Technologies Inc. ASUS AH3450 Series supported 1 ATI ASUS AH34xx +ATI Technologies Inc. ASUS AH3650 Series supported 3 ATI ASUS AH36xx +ATI Technologies Inc. ASUS AH4650 Series supported 3 ATI ASUS AH46xx +ATI Technologies Inc. ASUS ARES supported 0 ATI Technologies +ATI Technologies Inc. ASUS EAH2900 Series supported 0 ATI Technologies +ATI Technologies Inc. ASUS EAH3450 Series supported 1 ATI ASUS AH34xx +ATI Technologies Inc. ASUS EAH3650 Series supported 3 ATI ASUS AH36xx +ATI Technologies Inc. ASUS EAH4350 series supported 1 ATI ASUS EAH43xx +ATI Technologies Inc. ASUS EAH4550 series supported 1 ATI ASUS EAH45xx +ATI Technologies Inc. ASUS EAH4650 series supported 3 ATI ASUS AH46xx +ATI Technologies Inc. ASUS EAH4670 series supported 3 ATI ASUS AH46xx +ATI Technologies Inc. ASUS EAH4750 Series supported 0 ATI Technologies +ATI Technologies Inc. ASUS EAH4770 Series supported 0 ATI Technologies +ATI Technologies Inc. ASUS EAH4770 series supported 0 ATI Technologies +ATI Technologies Inc. ASUS EAH4850 series supported 3 ATI ASUS EAH48xx +ATI Technologies Inc. ASUS EAH5450 Series supported 0 ATI Technologies +ATI Technologies Inc. ASUS EAH5550 Series supported 0 ATI Technologies +ATI Technologies Inc. ASUS EAH5570 series supported 0 ATI Technologies +ATI Technologies Inc. ASUS EAH5670 Series supported 0 ATI Technologies +ATI Technologies Inc. ASUS EAH5750 Series supported 3 ATI ASUS EAH57xx +ATI Technologies Inc. ASUS EAH5770 Series supported 3 ATI ASUS EAH57xx +ATI Technologies Inc. ASUS EAH5830 Series supported 3 ATI ASUS EAH58xx +ATI Technologies Inc. ASUS EAH5850 Series supported 3 ATI ASUS EAH58xx +ATI Technologies Inc. ASUS EAH5870 Series supported 3 ATI ASUS EAH58xx +ATI Technologies Inc. ASUS EAH5970 Series supported 0 ATI Technologies +ATI Technologies Inc. ASUS EAH6850 Series supported 0 ATI Technologies +ATI Technologies Inc. ASUS EAH6870 Series supported 0 ATI Technologies +ATI Technologies Inc. ASUS EAH6950 Series supported 0 ATI Technologies +ATI Technologies Inc. ASUS EAH6970 Series supported 0 ATI Technologies +ATI Technologies Inc. ASUS EAHG4670 series supported 0 ATI Technologies +ATI Technologies Inc. ASUS Extreme AX600 Series supported 0 ATI Technologies +ATI Technologies Inc. ASUS Extreme AX600XT-TD supported 0 ATI Technologies +ATI Technologies Inc. ASUS X1300 Series x86/SSE2 supported 3 ATI ASUS Radeon X1xxx +ATI Technologies Inc. ASUS X1550 Series supported 3 ATI ASUS Radeon X1xxx +ATI Technologies Inc. ASUS X1950 Series x86/SSE2 supported 3 ATI ASUS Radeon X1xxx +ATI Technologies Inc. ASUS X800 Series supported 0 ATI Technologies +ATI Technologies Inc. ASUS X850 Series supported 0 ATI Technologies +ATI Technologies Inc. ATI All-in-Wonder HD supported 1 ATI All-in-Wonder HD +ATI Technologies Inc. ATI FirePro 2260 supported 1 ATI FirePro 2000 +ATI Technologies Inc. ATI FirePro 2450 supported 1 ATI FirePro 2000 +ATI Technologies Inc. ATI FirePro M5800 supported 3 ATI FirePro M5800 +ATI Technologies Inc. ATI FirePro M7740 supported 3 ATI FirePro M7740 +ATI Technologies Inc. ATI FirePro M7820 supported 3 ATI FirePro M7820 +ATI Technologies Inc. ATI FirePro V3700 (FireGL) supported 0 ATI FireGL +ATI Technologies Inc. ATI FirePro V3800 supported 1 ATI FirePro 3000 +ATI Technologies Inc. ATI FirePro V4800 supported 2 ATI FirePro 4000 +ATI Technologies Inc. ATI FirePro V4800 (FireGL) supported 0 ATI FireGL +ATI Technologies Inc. ATI FirePro V5800 supported 3 ATI FirePro 5000 +ATI Technologies Inc. ATI FirePro V7800 supported 3 ATI FirePro 7000 +ATI Technologies Inc. ATI MOBILITY RADEON 9XXX x86/SSE2 supported 0 ATI Mobility Radeon Xxxx +ATI Technologies Inc. ATI MOBILITY RADEON HD 3450 supported 2 ATI Mobility Radeon HD 3400 +ATI Technologies Inc. ATI MOBILITY RADEON X1600 supported 0 ATI Radeon X1xxx +ATI Technologies Inc. ATI MOBILITY RADEON X2300 supported 0 ATI Mobility Radeon X2xxx +ATI Technologies Inc. ATI MOBILITY RADEON X2300 HD x86/SSE2 supported 0 ATI Mobility Radeon X2xxx +ATI Technologies Inc. ATI MOBILITY RADEON X2300 x86/MMX/3DNow!/SSE2 supported 0 ATI Mobility Radeon X2xxx +ATI Technologies Inc. ATI MOBILITY RADEON X2300 x86/SSE2 supported 0 ATI Mobility Radeon X2xxx +ATI Technologies Inc. ATI MOBILITY RADEON X300 supported 1 ATI Mobility Radeon X3xx +ATI Technologies Inc. ATI MOBILITY RADEON X600 supported 1 ATI Mobility Radeon X6xx +ATI Technologies Inc. ATI MOBILITY RADEON XPRESS 200 supported 0 ATI Mobility Radeon Xxxx +ATI Technologies Inc. ATI Mobility FireGL V5700 supported 1 ATI FireGL 5xxx +ATI Technologies Inc. ATI Mobility Radeon 4100 supported 0 ATI Mobility Radeon 4100 +ATI Technologies Inc. ATI Mobility Radeon Graphics supported 0 ATI Mobility Radeon +ATI Technologies Inc. ATI Mobility Radeon HD 2300 supported 1 ATI Mobility Radeon HD 2300 +ATI Technologies Inc. ATI Mobility Radeon HD 2400 supported 1 ATI Mobility Radeon HD 2400 +ATI Technologies Inc. ATI Mobility Radeon HD 2400 XT supported 1 ATI Mobility Radeon HD 2400 +ATI Technologies Inc. ATI Mobility Radeon HD 2600 supported 3 ATI Mobility Radeon HD 2600 +ATI Technologies Inc. ATI Mobility Radeon HD 2600 XT supported 3 ATI Mobility Radeon HD 2600 +ATI Technologies Inc. ATI Mobility Radeon HD 2700 supported 3 ATI Mobility Radeon HD 2700 +ATI Technologies Inc. ATI Mobility Radeon HD 3400 Series supported 2 ATI Mobility Radeon HD 3400 +ATI Technologies Inc. ATI Mobility Radeon HD 3430 supported 2 ATI Mobility Radeon HD 3400 +ATI Technologies Inc. ATI Mobility Radeon HD 3450 supported 2 ATI Mobility Radeon HD 3400 +ATI Technologies Inc. ATI Mobility Radeon HD 3470 supported 2 ATI Mobility Radeon HD 3400 +ATI Technologies Inc. ATI Mobility Radeon HD 3470 Hybrid X2 supported 2 ATI Mobility Radeon HD 3400 +ATI Technologies Inc. ATI Mobility Radeon HD 3650 supported 3 ATI Mobility Radeon HD 3600 +ATI Technologies Inc. ATI Mobility Radeon HD 4200 supported 2 ATI Mobility Radeon HD 4200 +ATI Technologies Inc. ATI Mobility Radeon HD 4200 Series supported 2 ATI Mobility Radeon HD 4200 +ATI Technologies Inc. ATI Mobility Radeon HD 4225 supported 2 ATI Mobility Radeon HD 4200 +ATI Technologies Inc. ATI Mobility Radeon HD 4225 Series supported 2 ATI Mobility Radeon HD 4200 +ATI Technologies Inc. ATI Mobility Radeon HD 4250 supported 2 ATI Mobility Radeon HD 4200 +ATI Technologies Inc. ATI Mobility Radeon HD 4250 Graphics supported 2 ATI Mobility Radeon HD 4200 +ATI Technologies Inc. ATI Mobility Radeon HD 4270 supported 2 ATI Mobility Radeon HD 4200 +ATI Technologies Inc. ATI Mobility Radeon HD 4300 Series supported 2 ATI Mobility Radeon HD 4300 +ATI Technologies Inc. ATI Mobility Radeon HD 4300/4500 Series supported 2 ATI Mobility Radeon HD 4300 +ATI Technologies Inc. ATI Mobility Radeon HD 4330 supported 2 ATI Mobility Radeon HD 4300 +ATI Technologies Inc. ATI Mobility Radeon HD 4330 Series supported 2 ATI Mobility Radeon HD 4300 +ATI Technologies Inc. ATI Mobility Radeon HD 4350 supported 2 ATI Mobility Radeon HD 4300 +ATI Technologies Inc. ATI Mobility Radeon HD 4350 Series supported 2 ATI Mobility Radeon HD 4300 +ATI Technologies Inc. ATI Mobility Radeon HD 4500 Series supported 3 ATI Mobility Radeon HD 4500 +ATI Technologies Inc. ATI Mobility Radeon HD 4500/5100 Series supported 3 ATI Mobility Radeon HD 4500 +ATI Technologies Inc. ATI Mobility Radeon HD 4530 supported 3 ATI Mobility Radeon HD 4500 +ATI Technologies Inc. ATI Mobility Radeon HD 4530 Series supported 3 ATI Mobility Radeon HD 4500 +ATI Technologies Inc. ATI Mobility Radeon HD 4550 supported 3 ATI Mobility Radeon HD 4500 +ATI Technologies Inc. ATI Mobility Radeon HD 4570 supported 3 ATI Mobility Radeon HD 4500 +ATI Technologies Inc. ATI Mobility Radeon HD 4600 Series supported 3 ATI Mobility Radeon HD 4600 +ATI Technologies Inc. ATI Mobility Radeon HD 4650 supported 3 ATI Mobility Radeon HD 4600 +ATI Technologies Inc. ATI Mobility Radeon HD 4650 Series supported 3 ATI Mobility Radeon HD 4600 +ATI Technologies Inc. ATI Mobility Radeon HD 4670 supported 3 ATI Mobility Radeon HD 4600 +ATI Technologies Inc. ATI Mobility Radeon HD 4830 Series supported 3 ATI Mobility Radeon HD 4800 +ATI Technologies Inc. ATI Mobility Radeon HD 4850 supported 3 ATI Mobility Radeon HD 4800 +ATI Technologies Inc. ATI Mobility Radeon HD 4870 supported 3 ATI Mobility Radeon HD 4800 +ATI Technologies Inc. ATI Mobility Radeon HD 5000 supported 0 ATI Mobility Radeon +ATI Technologies Inc. ATI Mobility Radeon HD 5000 Series supported 0 ATI Mobility Radeon +ATI Technologies Inc. ATI Mobility Radeon HD 5145 supported 2 ATI Mobility Radeon HD 5100 +ATI Technologies Inc. ATI Mobility Radeon HD 5165 supported 2 ATI Mobility Radeon HD 5100 +ATI Technologies Inc. ATI Mobility Radeon HD 530v supported 1 ATI Mobility Radeon HD 530v +ATI Technologies Inc. ATI Mobility Radeon HD 5400 Series supported 2 ATI Mobility Radeon HD 5400 +ATI Technologies Inc. ATI Mobility Radeon HD 540v supported 2 ATI Mobility Radeon HD 540v +ATI Technologies Inc. ATI Mobility Radeon HD 5430 supported 2 ATI Mobility Radeon HD 5400 +ATI Technologies Inc. ATI Mobility Radeon HD 5450 supported 2 ATI Mobility Radeon HD 5400 +ATI Technologies Inc. ATI Mobility Radeon HD 5450 Series supported 2 ATI Mobility Radeon HD 5400 +ATI Technologies Inc. ATI Mobility Radeon HD 545v supported 2 ATI Mobility Radeon HD 545v +ATI Technologies Inc. ATI Mobility Radeon HD 5470 supported 2 ATI Mobility Radeon HD 5400 +ATI Technologies Inc. ATI Mobility Radeon HD 550v supported 2 ATI Mobility Radeon HD 550v +ATI Technologies Inc. ATI Mobility Radeon HD 5600/5700 Series supported 2 ATI Mobility Radeon HD 5600 +ATI Technologies Inc. ATI Mobility Radeon HD 560v supported 2 ATI Mobility Radeon HD 560v +ATI Technologies Inc. ATI Mobility Radeon HD 5650 supported 2 ATI Mobility Radeon HD 5600 +ATI Technologies Inc. ATI Mobility Radeon HD 5700 Series supported 3 ATI Mobility Radeon HD 5700 +ATI Technologies Inc. ATI Mobility Radeon HD 5730 supported 3 ATI Mobility Radeon HD 5700 +ATI Technologies Inc. ATI Mobility Radeon HD 5800 Series supported 0 ATI Mobility Radeon +ATI Technologies Inc. ATI Mobility Radeon HD 5850 supported 0 ATI Mobility Radeon +ATI Technologies Inc. ATI Mobility Radeon HD 5870 supported 0 ATI Mobility Radeon +ATI Technologies Inc. ATI Mobility Radeon HD 6300 series supported 2 ATI Mobility Radeon HD 6300 +ATI Technologies Inc. ATI Mobility Radeon HD 6370 supported 2 ATI Mobility Radeon HD 6300 +ATI Technologies Inc. ATI Mobility Radeon HD 6470M supported 3 ATI Mobility Radeon HD 6400M +ATI Technologies Inc. ATI Mobility Radeon HD 6550 supported 3 ATI Mobility Radeon HD 6500M +ATI Technologies Inc. ATI Mobility Radeon HD 6570 supported 3 ATI Mobility Radeon HD 6500M +ATI Technologies Inc. ATI Mobility Radeon X1300 supported 0 ATI Radeon X1xxx +ATI Technologies Inc. ATI Mobility Radeon X1300 x86/MMX/3DNow!/SSE2 supported 0 ATI Radeon X1xxx +ATI Technologies Inc. ATI Mobility Radeon X1300 x86/SSE2 supported 0 ATI Radeon X1xxx +ATI Technologies Inc. ATI Mobility Radeon X1350 supported 0 ATI Radeon X1xxx +ATI Technologies Inc. ATI Mobility Radeon X1350 x86/SSE2 supported 0 ATI Radeon X1xxx +ATI Technologies Inc. ATI Mobility Radeon X1400 supported 0 ATI Radeon X1xxx +ATI Technologies Inc. ATI Mobility Radeon X1400 x86/SSE2 supported 0 ATI Radeon X1xxx +ATI Technologies Inc. ATI Mobility Radeon X1600 supported 0 ATI Radeon X1xxx +ATI Technologies Inc. ATI Mobility Radeon X1600 x86/SSE2 supported 0 ATI Radeon X1xxx +ATI Technologies Inc. ATI Mobility Radeon X1700 x86/SSE2 supported 0 ATI Radeon X1xxx +ATI Technologies Inc. ATI Mobility Radeon X2300 supported 0 ATI Mobility Radeon X2xxx +ATI Technologies Inc. ATI Mobility Radeon X2300 (Omega 3.8.442) supported 0 ATI Mobility Radeon X2xxx +ATI Technologies Inc. ATI Mobility Radeon X2300 x86 supported 0 ATI Mobility Radeon X2xxx +ATI Technologies Inc. ATI Mobility Radeon X2300 x86/MMX/3DNow!/SSE2 supported 0 ATI Mobility Radeon X2xxx +ATI Technologies Inc. ATI Mobility Radeon X2300 x86/SSE2 supported 0 ATI Mobility Radeon X2xxx +ATI Technologies Inc. ATI Mobility Radeon X2500 supported 0 ATI Mobility Radeon X2xxx +ATI Technologies Inc. ATI Mobility Radeon X2500 x86/SSE2 supported 0 ATI Mobility Radeon X2xxx +ATI Technologies Inc. ATI Mobility Radeon. HD 530v supported 1 ATI Mobility Radeon HD 530v +ATI Technologies Inc. ATI Mobility Radeon. HD 5470 supported 2 ATI Mobility Radeon HD 5400 +ATI Technologies Inc. ATI RADEON HD 3200 T25XX by CAMILO supported 0 ATI Radeon HD 3200 +ATI Technologies Inc. ATI RADEON XPRESS 1100 supported 0 ATI Radeon Xpress +ATI Technologies Inc. ATI RADEON XPRESS 200 Series supported 0 ATI Radeon Xpress +ATI Technologies Inc. ATI RADEON XPRESS 200 Series x86/SSE2 supported 0 ATI Radeon Xpress +ATI Technologies Inc. ATI RADEON XPRESS 200M SERIES supported 0 ATI Radeon Xpress +ATI Technologies Inc. ATI Radeon supported 0 ATI Technologies +ATI Technologies Inc. ATI Radeon 2100 supported 0 ATI Radeon 2100 +ATI Technologies Inc. ATI Radeon 2100 (Microsoft - WDDM) supported 0 ATI Radeon 2100 +ATI Technologies Inc. ATI Radeon 2100 Graphics supported 0 ATI Radeon 2100 +ATI Technologies Inc. ATI Radeon 3000 supported 0 ATI Radeon 3000 +ATI Technologies Inc. ATI Radeon 3000 Graphics supported 0 ATI Radeon 3000 +ATI Technologies Inc. ATI Radeon 3100 Graphics supported 1 ATI Radeon 3100 +ATI Technologies Inc. ATI Radeon 5xxx series supported 3 ATI Radeon 5xxx +ATI Technologies Inc. ATI Radeon 9550 / X1050 Series supported 0 ATI Radeon X1xxx +ATI Technologies Inc. ATI Radeon 9550 / X1050 Series x86/MMX/3DNow!/SSE supported 0 ATI Radeon X1xxx +ATI Technologies Inc. ATI Radeon 9550 / X1050 Series x86/SSE2 supported 0 ATI Radeon X1xxx +ATI Technologies Inc. ATI Radeon 9550 / X1050 Series(Microsoft - WDDM) supported 0 ATI Radeon X1xxx +ATI Technologies Inc. ATI Radeon 9600 / X1050 Series supported 0 ATI Radeon X1xxx +ATI Technologies Inc. ATI Radeon 9600/9550/X1050 Series supported 0 ATI Radeon X1xxx +ATI Technologies Inc. ATI Radeon BA Prototype OpenGL Engine supported 0 ATI Technologies +ATI Technologies Inc. ATI Radeon BB Prototype OpenGL Engine supported 0 ATI Technologies +ATI Technologies Inc. ATI Radeon Cedar PRO Prototype OpenGL Engine supported 2 AMD CEDAR (HD 5450) +ATI Technologies Inc. ATI Radeon Cypress PRO Prototype OpenGL Engine supported 3 AMD CYPRESS (HD 5800) +ATI Technologies Inc. ATI Radeon Graphics Processor supported 0 ATI Technologies +ATI Technologies Inc. ATI Radeon HD 2200 Graphics supported 0 ATI Technologies +ATI Technologies Inc. ATI Radeon HD 2350 supported 0 ATI Radeon HD 2300 +ATI Technologies Inc. ATI Radeon HD 2400 supported 1 ATI Radeon HD 2400 +ATI Technologies Inc. ATI Radeon HD 2400 OpenGL Engine supported 1 ATI Radeon HD 2400 +ATI Technologies Inc. ATI Radeon HD 2400 PRO supported 1 ATI Radeon HD 2400 +ATI Technologies Inc. ATI Radeon HD 2400 PRO AGP supported 1 ATI Radeon HD 2400 +ATI Technologies Inc. ATI Radeon HD 2400 Pro supported 1 ATI Radeon HD 2400 +ATI Technologies Inc. ATI Radeon HD 2400 Series supported 1 ATI Radeon HD 2400 +ATI Technologies Inc. ATI Radeon HD 2400 XT supported 1 ATI Radeon HD 2400 +ATI Technologies Inc. ATI Radeon HD 2400 XT OpenGL Engine supported 1 ATI Radeon HD 2400 +ATI Technologies Inc. ATI Radeon HD 2600 OpenGL Engine supported 2 ATI Radeon HD 2600 +ATI Technologies Inc. ATI Radeon HD 2600 PRO supported 2 ATI Radeon HD 2600 +ATI Technologies Inc. ATI Radeon HD 2600 PRO OpenGL Engine supported 2 ATI Radeon HD 2600 +ATI Technologies Inc. ATI Radeon HD 2600 Pro supported 2 ATI Radeon HD 2600 +ATI Technologies Inc. ATI Radeon HD 2600 Series supported 2 ATI Radeon HD 2600 +ATI Technologies Inc. ATI Radeon HD 2600 XT supported 2 ATI Radeon HD 2600 +ATI Technologies Inc. ATI Radeon HD 2900 GT supported 3 ATI Radeon HD 2900 +ATI Technologies Inc. ATI Radeon HD 2900 XT supported 3 ATI Radeon HD 2900 +ATI Technologies Inc. ATI Radeon HD 3200 Graphics supported 0 ATI Radeon HD 3200 +ATI Technologies Inc. ATI Radeon HD 3300 Graphics supported 1 ATI Radeon HD 3300 +ATI Technologies Inc. ATI Radeon HD 3400 Series supported 1 ATI Radeon HD 3400 +ATI Technologies Inc. ATI Radeon HD 3450 supported 1 ATI Radeon HD 3400 +ATI Technologies Inc. ATI Radeon HD 3450 - Dell Optiplex supported 1 ATI Radeon HD 3400 +ATI Technologies Inc. ATI Radeon HD 3470 supported 1 ATI Radeon HD 3400 +ATI Technologies Inc. ATI Radeon HD 3470 - Dell Optiplex supported 1 ATI Radeon HD 3400 +ATI Technologies Inc. ATI Radeon HD 3550 supported 1 ATI Radeon HD 3500 +ATI Technologies Inc. ATI Radeon HD 3600 Series supported 3 ATI Radeon HD 3600 +ATI Technologies Inc. ATI Radeon HD 3650 supported 3 ATI Radeon HD 3600 +ATI Technologies Inc. ATI Radeon HD 3650 AGP supported 3 ATI Radeon HD 3600 +ATI Technologies Inc. ATI Radeon HD 3730 supported 3 ATI Radeon HD 3700 +ATI Technologies Inc. ATI Radeon HD 3800 Series supported 3 ATI Radeon HD 3800 +ATI Technologies Inc. ATI Radeon HD 3850 supported 3 ATI Radeon HD 3800 +ATI Technologies Inc. ATI Radeon HD 3850 AGP supported 3 ATI Radeon HD 3800 +ATI Technologies Inc. ATI Radeon HD 3870 supported 3 ATI Radeon HD 3800 +ATI Technologies Inc. ATI Radeon HD 3870 X2 supported 3 ATI Radeon HD 3800 +ATI Technologies Inc. ATI Radeon HD 4200 supported 1 ATI Radeon HD 4200 +ATI Technologies Inc. ATI Radeon HD 4250 supported 1 ATI Radeon HD 4200 +ATI Technologies Inc. ATI Radeon HD 4250 Graphics supported 1 ATI Radeon HD 4200 +ATI Technologies Inc. ATI Radeon HD 4270 supported 1 ATI Radeon HD 4200 +ATI Technologies Inc. ATI Radeon HD 4290 supported 1 ATI Radeon HD 4200 +ATI Technologies Inc. ATI Radeon HD 4300 Series supported 1 ATI Radeon HD 4300 +ATI Technologies Inc. ATI Radeon HD 4300/4500 Series supported 1 ATI Radeon HD 4300 +ATI Technologies Inc. ATI Radeon HD 4350 supported 1 ATI Radeon HD 4300 +ATI Technologies Inc. ATI Radeon HD 4350 (Microsoft WDDM 1.1) supported 1 ATI Radeon HD 4300 +ATI Technologies Inc. ATI Radeon HD 4450 supported 1 ATI Radeon HD 4400 +ATI Technologies Inc. ATI Radeon HD 4500 Series supported 3 ATI Radeon HD 4500 +ATI Technologies Inc. ATI Radeon HD 4550 supported 3 ATI Radeon HD 4500 +ATI Technologies Inc. ATI Radeon HD 4600 Series supported 3 ATI Radeon HD 4600 +ATI Technologies Inc. ATI Radeon HD 4650 supported 3 ATI Radeon HD 4600 +ATI Technologies Inc. ATI Radeon HD 4670 supported 3 ATI Radeon HD 4600 +ATI Technologies Inc. ATI Radeon HD 4670 OpenGL Engine supported 3 ATI Radeon HD 4600 +ATI Technologies Inc. ATI Radeon HD 4700 Series supported 3 ATI Radeon HD 4700 +ATI Technologies Inc. ATI Radeon HD 4720 supported 3 ATI Radeon HD 4700 +ATI Technologies Inc. ATI Radeon HD 4730 supported 3 ATI Radeon HD 4700 +ATI Technologies Inc. ATI Radeon HD 4730 Series supported 3 ATI Radeon HD 4700 +ATI Technologies Inc. ATI Radeon HD 4750 supported 3 ATI Radeon HD 4700 +ATI Technologies Inc. ATI Radeon HD 4770 supported 3 ATI Radeon HD 4700 +ATI Technologies Inc. ATI Radeon HD 4800 Series supported 3 ATI Radeon HD 4800 +ATI Technologies Inc. ATI Radeon HD 4850 supported 3 ATI Radeon HD 4800 +ATI Technologies Inc. ATI Radeon HD 4850 OpenGL Engine supported 3 ATI Radeon HD 4800 +ATI Technologies Inc. ATI Radeon HD 4850 Series supported 3 ATI Radeon HD 4800 +ATI Technologies Inc. ATI Radeon HD 4870 supported 3 ATI Radeon HD 4800 +ATI Technologies Inc. ATI Radeon HD 4870 OpenGL Engine supported 3 ATI Radeon HD 4800 +ATI Technologies Inc. ATI Radeon HD 4870 X2 supported 3 ATI Radeon HD 4800 +ATI Technologies Inc. ATI Radeon HD 5400 Series supported 3 ATI Radeon HD 5400 +ATI Technologies Inc. ATI Radeon HD 5450 supported 3 ATI Radeon HD 5400 +ATI Technologies Inc. ATI Radeon HD 5500 Series supported 3 ATI Radeon HD 5500 +ATI Technologies Inc. ATI Radeon HD 5570 supported 3 ATI Radeon HD 5500 +ATI Technologies Inc. ATI Radeon HD 5600 Series supported 3 ATI Radeon HD 5600 +ATI Technologies Inc. ATI Radeon HD 5630 supported 3 ATI Radeon HD 5600 +ATI Technologies Inc. ATI Radeon HD 5670 supported 3 ATI Radeon HD 5600 +ATI Technologies Inc. ATI Radeon HD 5670 OpenGL Engine supported 3 ATI Radeon HD 5600 +ATI Technologies Inc. ATI Radeon HD 5700 Series supported 3 ATI Radeon HD 5700 +ATI Technologies Inc. ATI Radeon HD 5750 supported 3 ATI Radeon HD 5700 +ATI Technologies Inc. ATI Radeon HD 5750 OpenGL Engine supported 3 ATI Radeon HD 5700 +ATI Technologies Inc. ATI Radeon HD 5770 supported 3 ATI Radeon HD 5700 +ATI Technologies Inc. ATI Radeon HD 5770 OpenGL Engine supported 3 ATI Radeon HD 5700 +ATI Technologies Inc. ATI Radeon HD 5800 Series supported 3 ATI Radeon HD 5800 +ATI Technologies Inc. ATI Radeon HD 5850 supported 3 ATI Radeon HD 5800 +ATI Technologies Inc. ATI Radeon HD 5870 supported 3 ATI Radeon HD 5800 +ATI Technologies Inc. ATI Radeon HD 5870 OpenGL Engine supported 3 ATI Radeon HD 5800 +ATI Technologies Inc. ATI Radeon HD 5900 Series supported 3 ATI Radeon HD 5900 +ATI Technologies Inc. ATI Radeon HD 5970 supported 3 ATI Radeon HD 5900 +ATI Technologies Inc. ATI Radeon HD 6230 supported 2 ATI Radeon HD 6200 +ATI Technologies Inc. ATI Radeon HD 6250 supported 2 ATI Radeon HD 6200 +ATI Technologies Inc. ATI Radeon HD 6350 supported 2 ATI Radeon HD 6300 +ATI Technologies Inc. ATI Radeon HD 6390 supported 2 ATI Radeon HD 6300 +ATI Technologies Inc. ATI Radeon HD 6490M OpenGL Engine supported 3 ATI Radeon HD 6400 +ATI Technologies Inc. ATI Radeon HD 6510 supported 3 ATI Radeon HD 6500 +ATI Technologies Inc. ATI Radeon HD 6570M supported 3 ATI Radeon HD 6500 +ATI Technologies Inc. ATI Radeon HD 6750 supported 3 ATI Radeon HD 6700 +ATI Technologies Inc. ATI Radeon HD 6750M OpenGL Engine supported 3 ATI Radeon HD 6700 +ATI Technologies Inc. ATI Radeon HD 6770 supported 3 ATI Radeon HD 6700 +ATI Technologies Inc. ATI Radeon HD 6770M OpenGL Engine supported 3 ATI Radeon HD 6700 +ATI Technologies Inc. ATI Radeon HD 6800 Series supported 3 ATI Radeon HD 6800 +ATI Technologies Inc. ATI Radeon HD 6970M OpenGL Engine supported 3 ATI Radeon HD 6900 +ATI Technologies Inc. ATI Radeon HD3750 supported 3 ATI Radeon HD 3700 +ATI Technologies Inc. ATI Radeon HD4300/HD4500 series supported 1 ATI Radeon HD 4300 +ATI Technologies Inc. ATI Radeon HD4670 supported 3 ATI Radeon HD 4600 +ATI Technologies Inc. ATI Radeon Juniper LE Prototype OpenGL Engine supported 3 AMD JUNIPER (HD 5700) +ATI Technologies Inc. ATI Radeon RV710 Prototype OpenGL Engine supported 1 AMD RV710 (HD 4300) +ATI Technologies Inc. ATI Radeon RV730 Prototype OpenGL Engine supported 3 AMD RV730 (HD 4600) +ATI Technologies Inc. ATI Radeon RV770 Prototype OpenGL Engine supported 3 AMD RV770 (HD 4800) +ATI Technologies Inc. ATI Radeon RV790 Prototype OpenGL Engine supported 3 AMD RV790 (HD 4800) +ATI Technologies Inc. ATI Radeon Redwood PRO Prototype OpenGL Engine supported 3 AMD REDWOOD (HD 5500/5600) +ATI Technologies Inc. ATI Radeon Redwood XT Prototype OpenGL Engine supported 3 AMD REDWOOD (HD 5500/5600) +ATI Technologies Inc. ATI Radeon Whistler PRO/LP Prototype OpenGL Engine supported 0 ATI Technologies +ATI Technologies Inc. ATI Radeon X1050 supported 0 ATI Radeon X1xxx +ATI Technologies Inc. ATI Radeon X1050 Series supported 0 ATI Radeon X1xxx +ATI Technologies Inc. ATI Radeon X1200 supported 0 ATI Radeon X1xxx +ATI Technologies Inc. ATI Radeon X1200 Series supported 0 ATI Radeon X1xxx +ATI Technologies Inc. ATI Radeon X1200 Series x86/MMX/3DNow!/SSE2 supported 0 ATI Radeon X1xxx +ATI Technologies Inc. ATI Radeon X1250 supported 0 ATI Radeon X1xxx +ATI Technologies Inc. ATI Radeon X1250 x86/MMX/3DNow!/SSE2 supported 0 ATI Radeon X1xxx +ATI Technologies Inc. ATI Radeon X1270 supported 0 ATI Radeon X1xxx +ATI Technologies Inc. ATI Radeon X1270 x86/MMX/3DNow!/SSE2 supported 0 ATI Radeon X1xxx +ATI Technologies Inc. ATI Radeon X1300/X1550 Series supported 0 ATI Radeon X1xxx +ATI Technologies Inc. ATI Radeon X1550 Series supported 0 ATI Radeon X1xxx +ATI Technologies Inc. ATI Radeon X1600 OpenGL Engine supported 0 ATI Radeon X1xxx +ATI Technologies Inc. ATI Radeon X1900 OpenGL Engine supported 0 ATI Radeon X1xxx +ATI Technologies Inc. ATI Radeon X1950 GT supported 0 ATI Radeon X1xxx +ATI Technologies Inc. ATI Radeon X300/X550/X1050 Series supported 0 ATI Radeon X1xxx +ATI Technologies Inc. ATI Radeon Xpress 1100 supported 0 ATI Radeon Xpress +ATI Technologies Inc. ATI Radeon Xpress 1150 supported 0 ATI Radeon Xpress +ATI Technologies Inc. ATI Radeon Xpress 1150 x86/MMX/3DNow!/SSE2 supported 0 ATI Radeon Xpress +ATI Technologies Inc. ATI Radeon Xpress 1200 supported 0 ATI Radeon Xpress +ATI Technologies Inc. ATI Radeon Xpress 1200 Series supported 0 ATI Radeon Xpress +ATI Technologies Inc. ATI Radeon Xpress 1200 Series x86/MMX/3DNow!/SSE2 supported 0 ATI Radeon Xpress +ATI Technologies Inc. ATI Radeon Xpress 1200 x86/MMX/3DNow!/SSE2 supported 0 ATI Radeon Xpress +ATI Technologies Inc. ATI Radeon Xpress 1250 supported 0 ATI Radeon Xpress +ATI Technologies Inc. ATI Radeon Xpress 1250 x86/SSE2 supported 0 ATI Radeon Xpress +ATI Technologies Inc. ATI Radeon Xpress Series supported 0 ATI Radeon Xpress +ATI Technologies Inc. ATI Yamaha HD 9000 supported 0 ATI Technologies +ATI Technologies Inc. ATi RS880M supported 1 ATI RS880M +ATI Technologies Inc. Carte graphique VGA standard supported 0 ATI Technologies +ATI Technologies Inc. Diamond Radeon X1550 Series supported 0 ATI Radeon X1xxx +ATI Technologies Inc. EG JUNIPER supported 3 AMD JUNIPER (HD 5700) +ATI Technologies Inc. EG PARK supported 3 AMD PARK +ATI Technologies Inc. FireGL V3100 Pentium 4 (SSE2) supported 0 ATI FireGL +ATI Technologies Inc. FireMV 2400 PCI DDR x86 supported 0 ATI FireMV +ATI Technologies Inc. FireMV 2400 PCI DDR x86/SSE2 supported 0 ATI FireMV +ATI Technologies Inc. GeCube Radeon X1550 supported 0 ATI Radeon X1xxx +ATI Technologies Inc. Geforce 9500 GT supported 2 ATI Geforce 9500 GT +ATI Technologies Inc. Geforce 9500GT supported 2 ATI Geforce 9500 GT +ATI Technologies Inc. Geforce 9800 GT supported 2 ATI Geforce 9800 GT +ATI Technologies Inc. HD3730 supported 0 ATI Technologies +ATI Technologies Inc. HIGHTECH EXCALIBUR RADEON 9550SE Series supported 0 ATI Radeon 9500 +ATI Technologies Inc. HIGHTECH EXCALIBUR X700 PRO supported 0 ATI Technologies +ATI Technologies Inc. M21 x86/MMX/3DNow!/SSE2 supported 0 ATI Technologies +ATI Technologies Inc. M76M supported 3 ATI M76 +ATI Technologies Inc. MOBILITY RADEON 7500 DDR x86/SSE2 supported 0 ATI Mobility Radeon +ATI Technologies Inc. MOBILITY RADEON 9000 DDR x86/SSE2 supported 0 ATI Mobility Radeon +ATI Technologies Inc. MOBILITY RADEON 9000 IGPRADEON 9100 IGP DDR x86/SSE2 supported 0 ATI Mobility Radeon +ATI Technologies Inc. MOBILITY RADEON 9600 x86/SSE2 supported 0 ATI Mobility Radeon 9600 +ATI Technologies Inc. MOBILITY RADEON 9700 x86/SSE2 supported 1 ATI Mobility Radeon 9700 +ATI Technologies Inc. MOBILITY RADEON X300 x86/SSE2 supported 1 ATI Mobility Radeon X3xx +ATI Technologies Inc. MOBILITY RADEON X600 x86/SSE2 supported 1 ATI Mobility Radeon X6xx +ATI Technologies Inc. MOBILITY RADEON X700 SE x86 supported 1 ATI Mobility Radeon X7xx +ATI Technologies Inc. MOBILITY RADEON X700 x86/SSE2 supported 1 ATI Mobility Radeon X7xx +ATI Technologies Inc. MSI RX9550SE supported 1 ATI Radeon RX9550 +ATI Technologies Inc. Mobility Radeon X2300 HD supported 0 ATI Mobility Radeon X2xxx +ATI Technologies Inc. Mobility Radeon X2300 HD x86/SSE2 supported 0 ATI Mobility Radeon X2xxx +ATI Technologies Inc. RADEON 7000 DDR x86/MMX/3DNow!/SSE supported 0 ATI Radeon 7xxx +ATI Technologies Inc. RADEON 7000 DDR x86/SSE2 supported 0 ATI Radeon 7xxx +ATI Technologies Inc. RADEON 7500 DDR x86/MMX/3DNow!/SSE2 supported 0 ATI Radeon 7xxx +ATI Technologies Inc. RADEON 7500 DDR x86/SSE2 supported 0 ATI Radeon 7xxx +ATI Technologies Inc. RADEON 9100 IGP DDR x86/SSE2 supported 0 ATI Radeon 9100 +ATI Technologies Inc. RADEON 9200 DDR x86/MMX/3DNow!/SSE supported 0 ATI Radeon 9200 +ATI Technologies Inc. RADEON 9200 DDR x86/SSE2 supported 0 ATI Radeon 9200 +ATI Technologies Inc. RADEON 9200 PRO DDR x86/MMX/3DNow!/SSE supported 0 ATI Radeon 9200 +ATI Technologies Inc. RADEON 9200 Series DDR x86/MMX/3DNow!/SSE supported 0 ATI Radeon 9200 +ATI Technologies Inc. RADEON 9200 Series DDR x86/MMX/3DNow!/SSE2 supported 0 ATI Radeon 9200 +ATI Technologies Inc. RADEON 9200 Series DDR x86/SSE supported 0 ATI Radeon 9200 +ATI Technologies Inc. RADEON 9200 Series DDR x86/SSE2 supported 0 ATI Radeon 9200 +ATI Technologies Inc. RADEON 9200SE DDR x86/MMX/3DNow!/SSE2 supported 0 ATI Radeon 9200 +ATI Technologies Inc. RADEON 9200SE DDR x86/SSE2 supported 0 ATI Radeon 9200 +ATI Technologies Inc. RADEON 9250/9200 Series DDR x86/MMX/3DNow!/SSE supported 0 ATI Radeon 9200 +ATI Technologies Inc. RADEON 9250/9200 Series DDR x86/MMX/3DNow!/SSE2 supported 0 ATI Radeon 9200 +ATI Technologies Inc. RADEON 9250/9200 Series DDR x86/SSE2 supported 0 ATI Radeon 9200 +ATI Technologies Inc. RADEON 9500 supported 0 ATI Radeon 9500 +ATI Technologies Inc. RADEON 9550 x86/SSE2 supported 0 ATI Radeon 9500 +ATI Technologies Inc. RADEON 9600 SERIES supported 0 ATI Radeon 9600 +ATI Technologies Inc. RADEON 9600 SERIES x86/MMX/3DNow!/SSE2 supported 0 ATI Radeon 9600 +ATI Technologies Inc. RADEON 9600 TX x86/SSE2 supported 0 ATI Radeon 9600 +ATI Technologies Inc. RADEON 9600 x86/MMX/3DNow!/SSE2 supported 0 ATI Radeon 9600 +ATI Technologies Inc. RADEON 9600 x86/SSE2 supported 0 ATI Radeon 9600 +ATI Technologies Inc. RADEON 9700 PRO x86/MMX/3DNow!/SSE supported 1 ATI Radeon 9700 +ATI Technologies Inc. RADEON 9800 PRO supported 1 ATI Radeon 9800 +ATI Technologies Inc. RADEON 9800 x86/SSE2 supported 1 ATI Radeon 9800 +ATI Technologies Inc. RADEON IGP 340M DDR x86/SSE2 unsupported 0 ATI IGP 340M +ATI Technologies Inc. RADEON X300 Series x86/SSE2 supported 0 ATI Radeon X300 +ATI Technologies Inc. RADEON X300 x86/SSE2 supported 0 ATI Radeon X300 +ATI Technologies Inc. RADEON X300/X550 Series x86/SSE2 supported 0 ATI Radeon X300 +ATI Technologies Inc. RADEON X550 x86/MMX/3DNow!/SSE2 supported 0 ATI Radeon X500 +ATI Technologies Inc. RADEON X550 x86/SSE2 supported 0 ATI Radeon X500 +ATI Technologies Inc. RADEON X600 Series supported 1 ATI Radeon X600 +ATI Technologies Inc. RADEON X600 x86/SSE2 supported 1 ATI Radeon X600 +ATI Technologies Inc. RADEON X700 PRO x86/SSE2 supported 1 ATI Radeon X700 +ATI Technologies Inc. RADEON X800 SE x86/MMX/3DNow!/SSE2 supported 2 ATI Radeon X800 +ATI Technologies Inc. RADEON X800GT supported 2 ATI Radeon X800 +ATI Technologies Inc. RADEON XPRESS 200 Series SW TCL x86/MMX/3DNow!/SSE2 supported 0 ATI Radeon Xpress +ATI Technologies Inc. RADEON XPRESS 200 Series SW TCL x86/SSE2 supported 0 ATI Radeon Xpress +ATI Technologies Inc. RADEON XPRESS 200 Series x86/SSE2 supported 0 ATI Radeon Xpress +ATI Technologies Inc. RADEON XPRESS 200M Series SW TCL x86/MMX/3DNow!/SSE2 supported 0 ATI Radeon Xpress +ATI Technologies Inc. RADEON XPRESS 200M Series SW TCL x86/SSE2 supported 0 ATI Radeon Xpress +ATI Technologies Inc. RADEON XPRESS 200M Series x86/MMX/3DNow!/SSE2 supported 0 ATI Radeon Xpress +ATI Technologies Inc. RADEON XPRESS 200M Series x86/SSE2 supported 0 ATI Radeon Xpress +ATI Technologies Inc. RADEON XPRESS Series x86/MMX/3DNow!/SSE2 supported 0 ATI Radeon Xpress +ATI Technologies Inc. RADEON XPRESS Series x86/SSE2 supported 0 ATI Radeon Xpress +ATI Technologies Inc. RS740 supported 0 ATI Technologies +ATI Technologies Inc. RS780C supported 0 AMD RS780 (HD 3200) +ATI Technologies Inc. RS780M supported 0 AMD RS780 (HD 3200) +ATI Technologies Inc. RS880 supported 1 AMD RS880 (HD 4200) +ATI Technologies Inc. RV410 Pro x86/SSE2 supported 1 ATI RV410 (X700) +ATI Technologies Inc. RV790 supported 3 AMD RV790 (HD 4800) +ATI Technologies Inc. Radeon (TM) HD 6470M supported 0 ATI Technologies +ATI Technologies Inc. Radeon (TM) HD 6490M supported 0 ATI Technologies +ATI Technologies Inc. Radeon (TM) HD 6770M supported 0 ATI Technologies +ATI Technologies Inc. Radeon 7000 DDR x86/SSE2 supported 0 ATI Radeon 7xxx +ATI Technologies Inc. Radeon 7000 SDR x86/SSE2 supported 0 ATI Radeon 7xxx +ATI Technologies Inc. Radeon 7500 DDR x86/SSE2 supported 0 ATI Radeon 7xxx +ATI Technologies Inc. Radeon 9000 DDR x86/SSE2 supported 0 ATI Radeon 9000 +ATI Technologies Inc. Radeon DDR x86/MMX/3DNow!/SSE2 supported 0 ATI Radeon DDR +ATI Technologies Inc. Radeon DDR x86/SSE supported 0 ATI Radeon DDR +ATI Technologies Inc. Radeon DDR x86/SSE2 supported 0 ATI Radeon DDR +ATI Technologies Inc. Radeon HD 6310 supported 2 ATI Radeon HD 6300 +ATI Technologies Inc. Radeon HD 6800 Series supported 3 ATI Radeon HD 6800 +ATI Technologies Inc. Radeon SDR x86/SSE2 supported 0 ATI Technologies +ATI Technologies Inc. Radeon X1300 Series supported 0 ATI Radeon X1xxx +ATI Technologies Inc. Radeon X1300 Series x86/MMX/3DNow!/SSE2 supported 0 ATI Radeon X1xxx +ATI Technologies Inc. Radeon X1300 Series x86/SSE2 supported 0 ATI Radeon X1xxx +ATI Technologies Inc. Radeon X1300/X1550 Series supported 0 ATI Radeon X1xxx +ATI Technologies Inc. Radeon X1300/X1550 Series x86/SSE2 supported 0 ATI Radeon X1xxx +ATI Technologies Inc. Radeon X1550 64-bit (Microsoft - WDDM) supported 0 ATI Radeon X1xxx +ATI Technologies Inc. Radeon X1550 Series supported 0 ATI Radeon X1xxx +ATI Technologies Inc. Radeon X1550 Series x86/SSE2 supported 0 ATI Radeon X1xxx +ATI Technologies Inc. Radeon X1600 supported 0 ATI Radeon X1xxx +ATI Technologies Inc. Radeon X1600 Pro / X1300XT x86/MMX/3DNow!/SSE2 supported 0 ATI Radeon X1xxx +ATI Technologies Inc. Radeon X1600 Series x86/SSE2 supported 0 ATI Radeon X1xxx +ATI Technologies Inc. Radeon X1600/X1650 Series supported 0 ATI Radeon X1xxx +ATI Technologies Inc. Radeon X1650 Series supported 0 ATI Radeon X1xxx +ATI Technologies Inc. Radeon X1650 Series x86/MMX/3DNow!/SSE2 supported 0 ATI Radeon X1xxx +ATI Technologies Inc. Radeon X1650 Series x86/SSE2 supported 0 ATI Radeon X1xxx +ATI Technologies Inc. Radeon X1900 Series x86/MMX/3DNow!/SSE2 supported 0 ATI Radeon X1xxx +ATI Technologies Inc. Radeon X1950 Pro supported 0 ATI Radeon X1xxx +ATI Technologies Inc. Radeon X1950 Pro x86/MMX/3DNow!/SSE2 supported 0 ATI Radeon X1xxx +ATI Technologies Inc. Radeon X1950 Series supported 0 ATI Radeon X1xxx +ATI Technologies Inc. Radeon X1950 Series (Microsoft - WDDM) supported 0 ATI Radeon X1xxx +ATI Technologies Inc. Radeon X300/X550/X1050 Series supported 0 ATI Radeon X1xxx +ATI Technologies Inc. Radeon X550/X700 Series supported 0 ATI Radeon X500 +ATI Technologies Inc. Radeon X550XTX x86/MMX/3DNow!/SSE2 supported 0 ATI Radeon X500 +ATI Technologies Inc. SAPPHIRE RADEON X300SE supported 0 ATI Radeon X300 +ATI Technologies Inc. SAPPHIRE RADEON X300SE x86/MMX/3DNow!/SSE2 supported 0 ATI Radeon X300 +ATI Technologies Inc. SAPPHIRE RADEON X300SE x86/SSE2 supported 0 ATI Radeon X300 +ATI Technologies Inc. SAPPHIRE Radeon X1550 Series supported 0 ATI Radeon X1xxx +ATI Technologies Inc. SAPPHIRE Radeon X1550 Series x86/MMX/3DNow!/SSE2 supported 0 ATI Radeon X1xxx +ATI Technologies Inc. Sapphire Radeon HD 3730 supported 3 ATI Radeon HD 3700 +ATI Technologies Inc. Sapphire Radeon HD 3750 supported 3 ATI Radeon HD 3700 +ATI Technologies Inc. Standard VGA Graphics Adapter supported 0 ATI Technologies +ATI Technologies Inc. Tul, RADEON X600 PRO supported 0 ATI Technologies +ATI Technologies Inc. Tul, RADEON X600 PRO x86/SSE2 supported 0 ATI Technologies +ATI Technologies Inc. Tul, RADEON X700 PRO supported 0 ATI Technologies +ATI Technologies Inc. Tul, RADEON X700 PRO x86/MMX/3DNow!/SSE2 supported 0 ATI Technologies +ATI Technologies Inc. VisionTek Radeon 4350 supported 0 ATI Technologies +ATI Technologies Inc. VisionTek Radeon X1550 Series supported 0 ATI Radeon X1xxx +ATI Technologies Inc. WRESTLER 9802 supported 0 ATI Technologies +ATI Technologies Inc. WRESTLER 9803 supported 0 ATI Technologies +ATI Technologies Inc. XFX Radeon HD 4570 supported 3 ATI Radeon HD 4500 +ATI Technologies Inc. Yamaha ATI HD 9000da/s supported 0 ATI Technologies +ATI Technologies Inc. Yamaha ATI HD 9000da/s 2048 supported 0 ATI Technologies +Advanced Micro Devices, Inc. Mesa DRI R600 (RS780 9612) 20090101 x86/MMX+/3DNow!+/SSE2 TCL DRI2 supported 0 AMD RS780 (HD 3200) +Advanced Micro Devices, Inc. Mesa DRI R600 (RS880 9710) 20090101 x86/MMX+/3DNow!+/SSE2 TCL DRI2 supported 1 AMD RS880 (HD 4200) +Advanced Micro Devices, Inc. Mesa DRI R600 (RS880 9712) 20090101 TCL supported 1 AMD RS880 (HD 4200) +Advanced Micro Devices, Inc. Mesa DRI R600 (RV610 94C1) 20090101 x86/MMX+/3DNow!+/SSE2 TCL DRI2 supported 1 AMD RV610 (HD 2400) +Advanced Micro Devices, Inc. Mesa DRI R600 (RV610 94C9) 20090101 x86/MMX/SSE2 TCL DRI2 supported 1 AMD RV610 (HD 2400) +Advanced Micro Devices, Inc. Mesa DRI R600 (RV620 95C4) 20090101 x86/MMX/SSE2 TCL DRI2 supported 1 AMD RV620 (HD 3400) +Advanced Micro Devices, Inc. Mesa DRI R600 (RV620 95C5) 20090101 x86/MMX+/3DNow!+/SSE2 TCL DRI2 supported 1 AMD RV620 (HD 3400) +Advanced Micro Devices, Inc. Mesa DRI R600 (RV620 95C5) 20090101 x86/MMX/SSE2 TCL DRI2 supported 1 AMD RV620 (HD 3400) +Advanced Micro Devices, Inc. Mesa DRI R600 (RV635 9596) 20090101 x86/MMX+/3DNow!+/SSE TCL DRI2 supported 3 AMD RV635 (HD 3600) +Advanced Micro Devices, Inc. Mesa DRI R600 (RV670 9505) 20090101 x86/MMX+/3DNow!+/SSE2 TCL DRI2 supported 3 AMD RV670 (HD 3800) +Advanced Micro Devices, Inc. Mesa DRI R600 (RV710 9552) 20090101 x86/MMX/SSE2 TCL DRI2 supported 1 AMD RV710 (HD 4300) +Advanced Micro Devices, Inc. Mesa DRI R600 (RV730 9490) 20090101 x86/MMX+/3DNow!+/SSE2 TCL DRI2 supported 3 AMD RV730 (HD 4600) +Advanced Micro Devices, Inc. Mesa DRI R600 (RV730 9490) 20090101 x86/MMX/SSE2 TCL DRI2 supported 3 AMD RV730 (HD 4600) +Advanced Micro Devices, Inc. Mesa DRI R600 (RV730 9498) 20090101 TCL DRI2 supported 3 AMD RV730 (HD 4600) +Advanced Micro Devices, Inc. Mesa DRI R600 (RV770 9440) 20090101 x86/MMX+/3DNow!+/SSE2 TCL DRI2 supported 3 AMD RV770 (HD 4800) +Advanced Micro Devices, Inc. Mesa DRI R600 (RV770 9442) 20090101 x86/MMX/SSE2 TCL DRI2 supported 3 AMD RV770 (HD 4800) +Alex Mohr GL Hijacker! UNRECOGNIZED +Apple Software Renderer unsupported 0 Apple Software Renderer +DRI R300 Project Mesa DRI R300 (RS400 5954) 20090101 x86/MMX+/3DNow!+/SSE2 NO-TCL DRI2 supported 1 ATI R300 (9700) +DRI R300 Project Mesa DRI R300 (RS400 5975) 20090101 x86/MMX+/3DNow!+/SSE2 NO-TCL DRI2 supported 1 ATI R300 (9700) +DRI R300 Project Mesa DRI R300 (RS400 5A62) 20090101 x86/MMX/SSE2 NO-TCL DRI2 supported 1 ATI R300 (9700) +DRI R300 Project Mesa DRI R300 (RS600 7941) 20090101 x86/MMX/SSE2 NO-TCL unsupported 0 ATI RS600 (Xpress 3200) +DRI R300 Project Mesa DRI R300 (RS690 791F) 20090101 x86/MMX+/3DNow!+/SSE2 NO-TCL DRI2 supported 1 ATI R300 (9700) +DRI R300 Project Mesa DRI R300 (RV350 4151) 20090101 AGP 4x x86/MMX+/3DNow!+/SSE TCL supported 0 ATI RV350 (9600) +DRI R300 Project Mesa DRI R300 (RV350 4153) 20090101 AGP 8x x86/MMX+/3DNow!+/SSE TCL supported 0 ATI RV350 (9600) +DRI R300 Project Mesa DRI R300 (RV380 3150) 20090101 x86/MMX+/3DNow!+/SSE2 TCL DRI2 supported 0 ATI RV380 +DRI R300 Project Mesa DRI R300 (RV380 3150) 20090101 x86/MMX/SSE2 TCL DRI2 supported 0 ATI RV380 +DRI R300 Project Mesa DRI R300 (RV380 5B60) 20090101 x86/MMX/SSE2 TCL DRI2 supported 0 ATI RV380 +DRI R300 Project Mesa DRI R300 (RV380 5B62) 20090101 x86/MMX+/3DNow!+/SSE2 TCL DRI2 supported 0 ATI RV380 +DRI R300 Project Mesa DRI R300 (RV515 7145) 20090101 x86/MMX/SSE2 TCL DRI2 supported 1 ATI RV515 +DRI R300 Project Mesa DRI R300 (RV515 7146) 20090101 x86/MMX+/3DNow!+/SSE2 TCL DRI2 supported 1 ATI RV515 +DRI R300 Project Mesa DRI R300 (RV515 7146) 20090101 x86/MMX/SSE2 TCL DRI2 supported 1 ATI RV515 +DRI R300 Project Mesa DRI R300 (RV515 7149) 20090101 x86/MMX/SSE2 TCL DRI2 supported 1 ATI RV515 +DRI R300 Project Mesa DRI R300 (RV515 714A) 20090101 x86/MMX/SSE2 TCL supported 1 ATI RV515 +DRI R300 Project Mesa DRI R300 (RV515 714A) 20090101 x86/MMX/SSE2 TCL DRI2 supported 1 ATI RV515 +DRI R300 Project Mesa DRI R300 (RV530 71C4) 20090101 x86/MMX/SSE2 TCL DRI2 supported 1 ATI RV530 +GPU_CLASS_UNKNOWN UNRECOGNIZED +Humper Chromium UNRECOGNIZED +Intel UNRECOGNIZED +Intel HD Graphics Family supported 2 Intel HD Graphics +Intel 3D-Analyze v2.2 - http://www.tommti-systems.com UNRECOGNIZED +Intel 3D-Analyze v2.3 - http://www.tommti-systems.com UNRECOGNIZED +Intel 4 Series Internal Chipset UNRECOGNIZED +Intel 830M unsupported 0 Intel 830M +Intel 845G unsupported 0 Intel 845G +Intel 855GM unsupported 0 Intel 855GM +Intel 865G unsupported 0 Intel 865G +Intel 915G unsupported 0 Intel 915G +Intel 915GM unsupported 0 Intel 915GM +Intel 945G supported 0 Intel 945G +Intel 945GM supported 0 Intel 945GM +Intel 950 supported 0 Intel 950 +Intel 965 supported 0 Intel 965 +Intel B43 Express Chipset UNRECOGNIZED +Intel Bear Lake unsupported 0 Intel Bear Lake +Intel Broadwater unsupported 0 Intel Broadwater +Intel Brookdale unsupported 0 Intel Brookdale +Intel Cantiga unsupported 0 Intel Cantiga +Intel Eaglelake supported 0 Intel Eaglelake +Intel Familia Mobile 45 Express Chipset (Microsoft Corporation - WDDM 1.1) UNRECOGNIZED +Intel G33 unsupported 0 Intel G33 +Intel G41 supported 0 Intel G41 +Intel G41 Express Chipset supported 0 Intel G41 +Intel G45 supported 0 Intel G45 +Intel G45/G43 Express Chipset supported 0 Intel G45 +Intel Graphics Media Accelerator HD supported 0 Intel Graphics Media HD +Intel HD Graphics supported 2 Intel HD Graphics +Intel HD Graphics 100 supported 2 Intel HD Graphics +Intel HD Graphics 200 supported 2 Intel HD Graphics +Intel HD Graphics 200 BR-1101-00SH supported 2 Intel HD Graphics +Intel HD Graphics 200 BR-1101-00SJ supported 2 Intel HD Graphics +Intel HD Graphics 200 BR-1101-00SK supported 2 Intel HD Graphics +Intel HD Graphics 200 BR-1101-01M5 supported 2 Intel HD Graphics +Intel HD Graphics 200 BR-1101-01M6 supported 2 Intel HD Graphics +Intel HD Graphics BR-1004-01Y1 supported 2 Intel HD Graphics +Intel HD Graphics BR-1006-0364 supported 2 Intel HD Graphics +Intel HD Graphics BR-1006-0365 supported 2 Intel HD Graphics +Intel HD Graphics BR-1006-0366 supported 2 Intel HD Graphics +Intel HD Graphics BR-1007-02G4 supported 2 Intel HD Graphics +Intel HD Graphics BR-1101-04SY supported 2 Intel HD Graphics +Intel HD Graphics BR-1101-04SZ supported 2 Intel HD Graphics +Intel HD Graphics BR-1101-04T0 supported 2 Intel HD Graphics +Intel HD Graphics BR-1101-04T9 supported 2 Intel HD Graphics +Intel HD Graphics Family supported 2 Intel HD Graphics +Intel HD Graphics Family BR-1012-00Y8 supported 2 Intel HD Graphics +Intel HD Graphics Family BR-1012-00YF supported 2 Intel HD Graphics +Intel HD Graphics Family BR-1012-00ZD supported 2 Intel HD Graphics +Intel HD Graphics Family BR-1102-00ML supported 2 Intel HD Graphics +Intel Inc. Intel GMA 900 OpenGL Engine UNRECOGNIZED +Intel Inc. Intel GMA 950 OpenGL Engine supported 0 Intel 950 +Intel Inc. Intel GMA X3100 OpenGL Engine supported 0 Intel X3100 +Intel Inc. Intel HD Graphics 3000 OpenGL Engine supported 2 Intel HD Graphics +Intel Inc. Intel HD Graphics OpenGL Engine supported 2 Intel HD Graphics +Intel Inc. Intel HD xxxx OpenGL Engine UNRECOGNIZED +Intel Intel 845G unsupported 0 Intel 845G +Intel Intel 855GM unsupported 0 Intel 855GM +Intel Intel 865G unsupported 0 Intel 865G +Intel Intel 915G unsupported 0 Intel 915G +Intel Intel 915GM unsupported 0 Intel 915GM +Intel Intel 945G supported 0 Intel 945G +Intel Intel 945GM supported 0 Intel 945GM +Intel Intel 965/963 Graphics Media Accelerator supported 0 Intel 965 +Intel Intel Bear Lake B unsupported 0 Intel Bear Lake +Intel Intel Broadwater G unsupported 0 Intel Broadwater +Intel Intel Brookdale-G unsupported 0 Intel Brookdale +Intel Intel Calistoga UNRECOGNIZED +Intel Intel Cantiga unsupported 0 Intel Cantiga +Intel Intel Eaglelake supported 0 Intel Eaglelake +Intel Intel Grantsdale-G UNRECOGNIZED +Intel Intel HD Graphics 3000 supported 2 Intel HD Graphics +Intel Intel Lakeport UNRECOGNIZED +Intel Intel Montara-GM unsupported 0 Intel Montara +Intel Intel Pineview Platform supported 0 Intel Pineview +Intel Intel Springdale-G unsupported 0 Intel Springdale +Intel Mobile - famiglia Express Chipset 45 (Microsoft Corporation - WDDM 1.1) UNRECOGNIZED +Intel Mobile 4 Series supported 0 Intel Mobile 4 Series +Intel Mobile 4 Series Express Chipset Family supported 0 Intel Mobile 4 Series +Intel Mobile 45 Express Chipset Family (Microsoft Corporation - WDDM 1.1) UNRECOGNIZED +Intel Mobile HD Graphics supported 2 Intel HD Graphics +Intel Mobile SandyBridge HD Graphics supported 2 Intel HD Graphics +Intel Montara unsupported 0 Intel Montara +Intel Pineview supported 0 Intel Pineview +Intel Q45/Q43 Express Chipset UNRECOGNIZED +Intel Royal BNA Driver UNRECOGNIZED +Intel SandyBridge HD Graphics supported 2 Intel HD Graphics +Intel SandyBridge HD Graphics BR-1006-00V8 supported 2 Intel HD Graphics +Intel Springdale unsupported 0 Intel Springdale +Intel X3100 supported 0 Intel X3100 +Intergraph wcgdrv 06.05.06.18 UNRECOGNIZED +Intergraph wcgdrv 06.06.00.35 UNRECOGNIZED +LegendgrafiX Mobile 945 Express C/TitaniumGL/GAC/D3D ACCELERATION/6x86/1 THREADs | http://Legendgra... UNRECOGNIZED +LegendgrafiX NVIDIA GeForce GT 430/TitaniumGL/GAC/D3D ACCELERATION/6x86/1 THREADs | http://Legendgr... supported 3 NVIDIA GT 430M +Linden Lab Headless UNRECOGNIZED +Matrox unsupported 0 Matrox +Mesa unsupported 0 Mesa +Mesa Project Software Rasterizer unsupported 0 Mesa +NVIDIA /PCI/SSE2 UNRECOGNIZED +NVIDIA /PCI/SSE2/3DNOW! UNRECOGNIZED +NVIDIA 205 supported 0 NVIDIA G 205M +NVIDIA 210 supported 1 NVIDIA G 210 +NVIDIA 310 supported 2 NVIDIA G 310M +NVIDIA 310M supported 2 NVIDIA G 310M +NVIDIA 315 supported 2 NVIDIA G 315 +NVIDIA 315M supported 2 NVIDIA G 315 +NVIDIA 320M supported 2 NVIDIA G 320M +NVIDIA C51 supported 0 NVIDIA C51 +NVIDIA D10M2-20/PCI/SSE2 UNRECOGNIZED +NVIDIA D10P1-25/PCI/SSE2 UNRECOGNIZED +NVIDIA D10P1-30/PCI/SSE2 UNRECOGNIZED +NVIDIA D10P2-50/PCI/SSE2 UNRECOGNIZED +NVIDIA D11M2-30/PCI/SSE2 UNRECOGNIZED +NVIDIA D12-P1-35/PCI/SSE2 UNRECOGNIZED +NVIDIA D12U-15/PCI/SSE2 UNRECOGNIZED +NVIDIA D13M1-40/PCI/SSE2 UNRECOGNIZED +NVIDIA D13P1-40/PCI/SSE2 UNRECOGNIZED +NVIDIA D13U-10/PCI/SSE2 UNRECOGNIZED +NVIDIA D13U/PCI/SSE2 UNRECOGNIZED +NVIDIA D9M supported 1 NVIDIA D9M +NVIDIA D9M-20/PCI/SSE2 supported 1 NVIDIA D9M +NVIDIA Entry Graphics/PCI/SSE2 UNRECOGNIZED +NVIDIA Entry Graphics/PCI/SSE2/3DNOW! UNRECOGNIZED +NVIDIA G 102M supported 0 NVIDIA G102M +NVIDIA G 103M supported 0 NVIDIA G103M +NVIDIA G 105M supported 0 NVIDIA G105M +NVIDIA G 110M supported 0 NVIDIA G 110M +NVIDIA G100 supported 0 NVIDIA G100 +NVIDIA G102M supported 0 NVIDIA G102M +NVIDIA G103M supported 0 NVIDIA G103M +NVIDIA G105M supported 0 NVIDIA G105M +NVIDIA G210 supported 1 NVIDIA G 210 +NVIDIA G210M supported 1 NVIDIA G 210 +NVIDIA G70/PCI/SSE2 UNRECOGNIZED +NVIDIA G72 supported 1 NVIDIA G72 +NVIDIA G73 supported 1 NVIDIA G73 +NVIDIA G84 supported 2 NVIDIA G84 +NVIDIA G86 supported 3 NVIDIA G86 +NVIDIA G92 supported 3 NVIDIA G92 +NVIDIA G92-200/PCI/SSE2 supported 3 NVIDIA G92 +NVIDIA G94 supported 3 NVIDIA G94 +NVIDIA G96/PCI/SSE2 UNRECOGNIZED +NVIDIA G98/PCI/SSE2 UNRECOGNIZED +NVIDIA GT 120 supported 2 NVIDIA GT 120M +NVIDIA GT 130 supported 2 NVIDIA GT 130M +NVIDIA GT 130M supported 2 NVIDIA GT 130M +NVIDIA GT 140 supported 2 NVIDIA GT 140M +NVIDIA GT 150 supported 2 NVIDIA GT 150M +NVIDIA GT 160M supported 2 NVIDIA GT 160M +NVIDIA GT 220 supported 2 NVIDIA GT 220M +NVIDIA GT 220/PCI/SSE2 supported 2 NVIDIA GT 220M +NVIDIA GT 220/PCI/SSE2/3DNOW! supported 2 NVIDIA GT 220M +NVIDIA GT 230 supported 2 NVIDIA GT 230M +NVIDIA GT 230M supported 2 NVIDIA GT 230M +NVIDIA GT 240 supported 2 NVIDIA GT 240M +NVIDIA GT 240M supported 2 NVIDIA GT 240M +NVIDIA GT 250M supported 2 NVIDIA GT 250M +NVIDIA GT 260M supported 2 NVIDIA GT 260M +NVIDIA GT 320 supported 2 NVIDIA GT 320M +NVIDIA GT 320M supported 2 NVIDIA GT 320M +NVIDIA GT 330 supported 3 NVIDIA GT 330M +NVIDIA GT 330M supported 3 NVIDIA GT 330M +NVIDIA GT 340 supported 2 NVIDIA GT 340M +NVIDIA GT 420 supported 2 NVIDIA GT 420M +NVIDIA GT 430 supported 3 NVIDIA GT 430M +NVIDIA GT 440 supported 3 NVIDIA GT 440M +NVIDIA GT 450 supported 3 NVIDIA GT 450M +NVIDIA GT 520 supported 3 NVIDIA GT 520M +NVIDIA GT 540 supported 3 NVIDIA GT 540M +NVIDIA GT 540M supported 3 NVIDIA GT 540M +NVIDIA GT-120 supported 2 NVIDIA GT 120 +NVIDIA GT200/PCI/SSE2 UNRECOGNIZED +NVIDIA GTS 150 supported 2 NVIDIA GT 150M +NVIDIA GTS 240 supported 3 NVIDIA GTS 240 +NVIDIA GTS 250 supported 3 NVIDIA GTS 250 +NVIDIA GTS 350M supported 3 NVIDIA GTS 350M +NVIDIA GTS 360 supported 3 NVIDIA GTS 360 +NVIDIA GTS 360M supported 3 NVIDIA GTS 360M +NVIDIA GTS 450 supported 3 NVIDIA GTS 450 +NVIDIA GTX 260 supported 3 NVIDIA GTX 260 +NVIDIA GTX 260M supported 3 NVIDIA GTX 260 +NVIDIA GTX 270 supported 3 NVIDIA GTX 270 +NVIDIA GTX 280 supported 3 NVIDIA GTX 280 +NVIDIA GTX 285 supported 3 NVIDIA GTX 285 +NVIDIA GTX 290 supported 3 NVIDIA GTX 290 +NVIDIA GTX 460 supported 3 NVIDIA GTX 460 +NVIDIA GTX 460M supported 3 NVIDIA GTX 460M +NVIDIA GTX 465 supported 3 NVIDIA GTX 465 +NVIDIA GTX 470 supported 3 NVIDIA GTX 470 +NVIDIA GTX 470M supported 3 NVIDIA GTX 470M +NVIDIA GTX 480 supported 3 NVIDIA GTX 480 +NVIDIA GTX 480M supported 3 NVIDIA GTX 480M +NVIDIA GTX 550 Ti supported 3 NVIDIA GTX 550 +NVIDIA GTX 560 supported 3 NVIDIA GTX 560 +NVIDIA GTX 560 Ti supported 3 NVIDIA GTX 560 +NVIDIA GTX 570 supported 3 NVIDIA GTX 570 +NVIDIA GTX 580 supported 3 NVIDIA GTX 580 +NVIDIA GTX 590 supported 3 NVIDIA GTX 590 +NVIDIA GeForce UNRECOGNIZED +NVIDIA GeForce 2 supported 0 NVIDIA GeForce 2 +NVIDIA GeForce 205/PCI/SSE2 supported 2 NVIDIA 205 +NVIDIA GeForce 210 supported 2 NVIDIA 210 +NVIDIA GeForce 210/PCI/SSE2 supported 2 NVIDIA 210 +NVIDIA GeForce 210/PCI/SSE2/3DNOW! supported 2 NVIDIA 210 +NVIDIA GeForce 3 supported 0 NVIDIA GeForce 3 +NVIDIA GeForce 305M/PCI/SSE2 supported 1 NVIDIA 305M +NVIDIA GeForce 310/PCI/SSE2 supported 3 NVIDIA 310 +NVIDIA GeForce 310/PCI/SSE2/3DNOW! supported 3 NVIDIA 310 +NVIDIA GeForce 310M/PCI/SSE2 supported 1 NVIDIA 310M +NVIDIA GeForce 315/PCI/SSE2 supported 3 NVIDIA 315 +NVIDIA GeForce 315/PCI/SSE2/3DNOW! supported 3 NVIDIA 315 +NVIDIA GeForce 315M/PCI/SSE2 supported 2 NVIDIA 315M +NVIDIA GeForce 320M/PCI/SSE2 supported 2 NVIDIA 320M +NVIDIA GeForce 4 Go supported 0 NVIDIA GeForce 4 +NVIDIA GeForce 4 MX supported 0 NVIDIA GeForce 4 +NVIDIA GeForce 4 Ti supported 0 NVIDIA GeForce 4 +NVIDIA GeForce 405/PCI/SSE2 supported 1 NVIDIA G 405 +NVIDIA GeForce 6100 supported 0 NVIDIA GeForce 6100 +NVIDIA GeForce 6100 nForce 400/PCI/SSE2/3DNOW! supported 0 NVIDIA GeForce 6100 +NVIDIA GeForce 6100 nForce 405/PCI/SSE2 supported 0 NVIDIA GeForce 6100 +NVIDIA GeForce 6100 nForce 405/PCI/SSE2/3DNOW! supported 0 NVIDIA GeForce 6100 +NVIDIA GeForce 6100 nForce 420/PCI/SSE2/3DNOW! supported 0 NVIDIA GeForce 6100 +NVIDIA GeForce 6100 nForce 430/PCI/SSE2/3DNOW! supported 0 NVIDIA GeForce 6100 +NVIDIA GeForce 6100/PCI/SSE2/3DNOW! supported 0 NVIDIA GeForce 6100 +NVIDIA GeForce 6150 LE/PCI/SSE2/3DNOW! supported 0 NVIDIA GeForce 6100 +NVIDIA GeForce 6150/PCI/SSE2 supported 0 NVIDIA GeForce 6100 +NVIDIA GeForce 6150/PCI/SSE2/3DNOW! supported 0 NVIDIA GeForce 6100 +NVIDIA GeForce 6150SE nForce 430/PCI/SSE2 supported 0 NVIDIA GeForce 6100 +NVIDIA GeForce 6150SE nForce 430/PCI/SSE2/3DNOW! supported 0 NVIDIA GeForce 6100 +NVIDIA GeForce 6150SE/PCI/SSE2/3DNOW! supported 0 NVIDIA GeForce 6100 +NVIDIA GeForce 6200 supported 0 NVIDIA GeForce 6200 +NVIDIA GeForce 6200 A-LE/AGP/SSE/3DNOW! supported 0 NVIDIA GeForce 6200 +NVIDIA GeForce 6200 A-LE/AGP/SSE2 supported 0 NVIDIA GeForce 6200 +NVIDIA GeForce 6200 A-LE/AGP/SSE2/3DNOW! supported 0 NVIDIA GeForce 6200 +NVIDIA GeForce 6200 LE/PCI/SSE2 supported 0 NVIDIA GeForce 6200 +NVIDIA GeForce 6200 LE/PCI/SSE2/3DNOW! supported 0 NVIDIA GeForce 6200 +NVIDIA GeForce 6200 TurboCache(TM)/PCI/SSE2 supported 0 NVIDIA GeForce 6200 +NVIDIA GeForce 6200 TurboCache(TM)/PCI/SSE2/3DNOW! supported 0 NVIDIA GeForce 6200 +NVIDIA GeForce 6200/AGP/SSE/3DNOW! supported 0 NVIDIA GeForce 6200 +NVIDIA GeForce 6200/AGP/SSE2 supported 0 NVIDIA GeForce 6200 +NVIDIA GeForce 6200/AGP/SSE2/3DNOW! supported 0 NVIDIA GeForce 6200 +NVIDIA GeForce 6200/PCI/SSE/3DNOW! supported 0 NVIDIA GeForce 6200 +NVIDIA GeForce 6200/PCI/SSE2 supported 0 NVIDIA GeForce 6200 +NVIDIA GeForce 6200/PCI/SSE2/3DNOW! supported 0 NVIDIA GeForce 6200 +NVIDIA GeForce 6200SE TurboCache(TM)/PCI/SSE2/3DNOW! supported 0 NVIDIA GeForce 6200 +NVIDIA GeForce 6500 supported 0 NVIDIA GeForce 6500 +NVIDIA GeForce 6500/PCI/SSE2 supported 0 NVIDIA GeForce 6500 +NVIDIA GeForce 6600 supported 1 NVIDIA GeForce 6600 +NVIDIA GeForce 6600 GT/AGP/SSE/3DNOW! supported 1 NVIDIA GeForce 6600 +NVIDIA GeForce 6600 GT/AGP/SSE2 supported 1 NVIDIA GeForce 6600 +NVIDIA GeForce 6600 GT/PCI/SSE/3DNOW! supported 1 NVIDIA GeForce 6600 +NVIDIA GeForce 6600 GT/PCI/SSE2 supported 1 NVIDIA GeForce 6600 +NVIDIA GeForce 6600 GT/PCI/SSE2/3DNOW! supported 1 NVIDIA GeForce 6600 +NVIDIA GeForce 6600 LE/PCI/SSE2 supported 1 NVIDIA GeForce 6600 +NVIDIA GeForce 6600/AGP/SSE/3DNOW! supported 1 NVIDIA GeForce 6600 +NVIDIA GeForce 6600/AGP/SSE2 supported 1 NVIDIA GeForce 6600 +NVIDIA GeForce 6600/AGP/SSE2/3DNOW! supported 1 NVIDIA GeForce 6600 +NVIDIA GeForce 6600/PCI/SSE2 supported 1 NVIDIA GeForce 6600 +NVIDIA GeForce 6600/PCI/SSE2/3DNOW! supported 1 NVIDIA GeForce 6600 +NVIDIA GeForce 6700 supported 2 NVIDIA GeForce 6700 +NVIDIA GeForce 6800 supported 2 NVIDIA GeForce 6800 +NVIDIA GeForce 6800 GS/PCI/SSE2/3DNOW! supported 2 NVIDIA GeForce 6800 +NVIDIA GeForce 6800 GT/AGP/SSE2 supported 2 NVIDIA GeForce 6800 +NVIDIA GeForce 6800 GT/PCI/SSE2 supported 2 NVIDIA GeForce 6800 +NVIDIA GeForce 6800 XT/AGP/SSE2 supported 2 NVIDIA GeForce 6800 +NVIDIA GeForce 6800 XT/PCI/SSE2 supported 2 NVIDIA GeForce 6800 +NVIDIA GeForce 6800/PCI/SSE2 supported 2 NVIDIA GeForce 6800 +NVIDIA GeForce 6800/PCI/SSE2/3DNOW! supported 2 NVIDIA GeForce 6800 +NVIDIA GeForce 7000 supported 0 NVIDIA GeForce 7000 +NVIDIA GeForce 7000M supported 0 NVIDIA GeForce 7000 +NVIDIA GeForce 7000M / nForce 610M/PCI/SSE2 supported 0 NVIDIA GeForce 7000 +NVIDIA GeForce 7000M / nForce 610M/PCI/SSE2/3DNOW! supported 0 NVIDIA GeForce 7000 +NVIDIA GeForce 7025 / NVIDIA nForce 630a/PCI/SSE2/3DNOW! supported 0 NVIDIA GeForce 7000 +NVIDIA GeForce 7025 / nForce 630a/PCI/SSE2 supported 0 NVIDIA GeForce 7000 +NVIDIA GeForce 7025 / nForce 630a/PCI/SSE2/3DNOW! supported 0 NVIDIA GeForce 7000 +NVIDIA GeForce 7050 / NVIDIA nForce 610i/PCI/SSE2 supported 0 NVIDIA GeForce 7000 +NVIDIA GeForce 7050 / NVIDIA nForce 620i/PCI/SSE2 supported 0 NVIDIA GeForce 7000 +NVIDIA GeForce 7050 / nForce 610i/PCI/SSE2 supported 0 NVIDIA GeForce 7000 +NVIDIA GeForce 7050 / nForce 620i/PCI/SSE2 supported 0 NVIDIA GeForce 7000 +NVIDIA GeForce 7050 PV / NVIDIA nForce 630a/PCI/SSE2/3DNOW! supported 0 NVIDIA GeForce 7000 +NVIDIA GeForce 7050 PV / nForce 630a/PCI/SSE2 supported 0 NVIDIA GeForce 7000 +NVIDIA GeForce 7050 PV / nForce 630a/PCI/SSE2/3DNOW! supported 0 NVIDIA GeForce 7000 +NVIDIA GeForce 7050 SE / NVIDIA nForce 630a/PCI/SSE2/3DNOW! supported 0 NVIDIA GeForce 7000 +NVIDIA GeForce 7100 supported 0 NVIDIA GeForce 7100 +NVIDIA GeForce 7100 / NVIDIA nForce 620i/PCI/SSE2 supported 0 NVIDIA GeForce 7100 +NVIDIA GeForce 7100 / NVIDIA nForce 630i/PCI/SSE2 supported 0 NVIDIA GeForce 7100 +NVIDIA GeForce 7100 / nForce 630i/PCI/SSE2 supported 0 NVIDIA GeForce 7100 +NVIDIA GeForce 7100 GS/PCI/SSE2 supported 0 NVIDIA GeForce 7100 +NVIDIA GeForce 7100 GS/PCI/SSE2/3DNOW! supported 0 NVIDIA GeForce 7100 +NVIDIA GeForce 7150M / nForce 630M/PCI/SSE2 supported 0 NVIDIA GeForce 7100 +NVIDIA GeForce 7150M / nForce 630M/PCI/SSE2/3DNOW! supported 0 NVIDIA GeForce 7100 +NVIDIA GeForce 7300 supported 1 NVIDIA GeForce 7300 +NVIDIA GeForce 7300 GS/PCI/SSE2 supported 1 NVIDIA GeForce 7300 +NVIDIA GeForce 7300 GS/PCI/SSE2/3DNOW! supported 1 NVIDIA GeForce 7300 +NVIDIA GeForce 7300 GT/AGP/SSE2 supported 1 NVIDIA GeForce 7300 +NVIDIA GeForce 7300 GT/AGP/SSE2/3DNOW! supported 1 NVIDIA GeForce 7300 +NVIDIA GeForce 7300 GT/PCI/SSE2 supported 1 NVIDIA GeForce 7300 +NVIDIA GeForce 7300 GT/PCI/SSE2/3DNOW! supported 1 NVIDIA GeForce 7300 +NVIDIA GeForce 7300 LE/PCI/SSE2 supported 1 NVIDIA GeForce 7300 +NVIDIA GeForce 7300 LE/PCI/SSE2/3DNOW! supported 1 NVIDIA GeForce 7300 +NVIDIA GeForce 7300 SE/7200 GS/PCI/SSE2 supported 1 NVIDIA GeForce 7300 +NVIDIA GeForce 7300 SE/7200 GS/PCI/SSE2/3DNOW! supported 1 NVIDIA GeForce 7300 +NVIDIA GeForce 7300 SE/PCI/SSE2 supported 1 NVIDIA GeForce 7300 +NVIDIA GeForce 7300 SE/PCI/SSE2/3DNOW! supported 1 NVIDIA GeForce 7300 +NVIDIA GeForce 7350 LE/PCI/SSE2 supported 1 NVIDIA GeForce 7300 +NVIDIA GeForce 7500 supported 1 NVIDIA GeForce 7500 +NVIDIA GeForce 7500 LE/PCI/SSE2 supported 1 NVIDIA GeForce 7500 +NVIDIA GeForce 7500 LE/PCI/SSE2/3DNOW! supported 1 NVIDIA GeForce 7500 +NVIDIA GeForce 7600 supported 2 NVIDIA GeForce 7600 +NVIDIA GeForce 7600 GS/AGP/SSE2 supported 2 NVIDIA GeForce 7600 +NVIDIA GeForce 7600 GS/AGP/SSE2/3DNOW! supported 2 NVIDIA GeForce 7600 +NVIDIA GeForce 7600 GS/PCI/SSE2 supported 2 NVIDIA GeForce 7600 +NVIDIA GeForce 7600 GS/PCI/SSE2/3DNOW! supported 2 NVIDIA GeForce 7600 +NVIDIA GeForce 7600 GT/AGP/SSE/3DNOW! supported 2 NVIDIA GeForce 7600 +NVIDIA GeForce 7600 GT/AGP/SSE2 supported 2 NVIDIA GeForce 7600 +NVIDIA GeForce 7600 GT/PCI/SSE2 supported 2 NVIDIA GeForce 7600 +NVIDIA GeForce 7600 GT/PCI/SSE2/3DNOW! supported 2 NVIDIA GeForce 7600 +NVIDIA GeForce 7650 GS/PCI/SSE2 supported 2 NVIDIA GeForce 7600 +NVIDIA GeForce 7800 supported 2 NVIDIA GeForce 7800 +NVIDIA GeForce 7800 GS/AGP/SSE2 supported 2 NVIDIA GeForce 7800 +NVIDIA GeForce 7800 GS/AGP/SSE2/3DNOW! supported 2 NVIDIA GeForce 7800 +NVIDIA GeForce 7800 GT/PCI/SSE2 supported 2 NVIDIA GeForce 7800 +NVIDIA GeForce 7800 GTX/PCI/SSE2 supported 2 NVIDIA GeForce 7800 +NVIDIA GeForce 7800 GTX/PCI/SSE2/3DNOW! supported 2 NVIDIA GeForce 7800 +NVIDIA GeForce 7900 supported 2 NVIDIA GeForce 7900 +NVIDIA GeForce 7900 GS/PCI/SSE2 supported 2 NVIDIA GeForce 7900 +NVIDIA GeForce 7900 GS/PCI/SSE2/3DNOW! supported 2 NVIDIA GeForce 7900 +NVIDIA GeForce 7900 GT/GTO/PCI/SSE2 supported 2 NVIDIA GeForce 7900 +NVIDIA GeForce 7900 GT/PCI/SSE2/3DNOW! supported 2 NVIDIA GeForce 7900 +NVIDIA GeForce 7900 GTX/PCI/SSE2 supported 2 NVIDIA GeForce 7900 +NVIDIA GeForce 7950 GT/PCI/SSE2 supported 2 NVIDIA GeForce 7900 +NVIDIA GeForce 7950 GT/PCI/SSE2/3DNOW! supported 2 NVIDIA GeForce 7900 +NVIDIA GeForce 8100 supported 1 NVIDIA GeForce 8100 +NVIDIA GeForce 8100 / nForce 720a/PCI/SSE2/3DNOW! supported 1 NVIDIA GeForce 8100 +NVIDIA GeForce 8200 supported 1 NVIDIA GeForce 8200 +NVIDIA GeForce 8200/PCI/SSE2 supported 1 NVIDIA GeForce 8200 +NVIDIA GeForce 8200/PCI/SSE2/3DNOW! supported 1 NVIDIA GeForce 8200 +NVIDIA GeForce 8200M supported 1 NVIDIA GeForce 8200M +NVIDIA GeForce 8200M G/PCI/SSE2 supported 1 NVIDIA GeForce 8200M +NVIDIA GeForce 8200M G/PCI/SSE2/3DNOW! supported 1 NVIDIA GeForce 8200M +NVIDIA GeForce 8300 supported 1 NVIDIA GeForce 8300 +NVIDIA GeForce 8300 GS/PCI/SSE2 supported 1 NVIDIA GeForce 8300 +NVIDIA GeForce 8400 supported 1 NVIDIA GeForce 8400 +NVIDIA GeForce 8400 GS/PCI/SSE/3DNOW! supported 1 NVIDIA GeForce 8400 +NVIDIA GeForce 8400 GS/PCI/SSE2 supported 1 NVIDIA GeForce 8400 +NVIDIA GeForce 8400 GS/PCI/SSE2/3DNOW! supported 1 NVIDIA GeForce 8400 +NVIDIA GeForce 8400/PCI/SSE2/3DNOW! supported 1 NVIDIA GeForce 8400 +NVIDIA GeForce 8400GS/PCI/SSE2 supported 1 NVIDIA GeForce 8400 +NVIDIA GeForce 8400GS/PCI/SSE2/3DNOW! supported 1 NVIDIA GeForce 8400 +NVIDIA GeForce 8400M supported 1 NVIDIA GeForce 8400M +NVIDIA GeForce 8400M G/PCI/SSE2 supported 1 NVIDIA GeForce 8400M +NVIDIA GeForce 8400M G/PCI/SSE2/3DNOW! supported 1 NVIDIA GeForce 8400M +NVIDIA GeForce 8400M GS/PCI/SSE2 supported 1 NVIDIA GeForce 8400M +NVIDIA GeForce 8400M GS/PCI/SSE2/3DNOW! supported 1 NVIDIA GeForce 8400M +NVIDIA GeForce 8400M GT/PCI/SSE2 supported 1 NVIDIA GeForce 8400M +NVIDIA GeForce 8500 supported 3 NVIDIA GeForce 8500 +NVIDIA GeForce 8500 GT/PCI/SSE2 supported 3 NVIDIA GeForce 8500 +NVIDIA GeForce 8500 GT/PCI/SSE2/3DNOW! supported 3 NVIDIA GeForce 8500 +NVIDIA GeForce 8600 supported 3 NVIDIA GeForce 8600 +NVIDIA GeForce 8600 GS/PCI/SSE2 supported 3 NVIDIA GeForce 8600 +NVIDIA GeForce 8600 GS/PCI/SSE2/3DNOW! supported 3 NVIDIA GeForce 8600 +NVIDIA GeForce 8600 GT/PCI/SSE2 supported 3 NVIDIA GeForce 8600 +NVIDIA GeForce 8600 GT/PCI/SSE2/3DNOW! supported 3 NVIDIA GeForce 8600 +NVIDIA GeForce 8600 GTS/PCI/SSE2 supported 3 NVIDIA GeForce 8600 +NVIDIA GeForce 8600 GTS/PCI/SSE2/3DNOW! supported 3 NVIDIA GeForce 8600 +NVIDIA GeForce 8600GS/PCI/SSE2 supported 3 NVIDIA GeForce 8600 +NVIDIA GeForce 8600M supported 1 NVIDIA GeForce 8600M +NVIDIA GeForce 8600M GS/PCI/SSE2 supported 1 NVIDIA GeForce 8600M +NVIDIA GeForce 8600M GS/PCI/SSE2/3DNOW! supported 1 NVIDIA GeForce 8600M +NVIDIA GeForce 8600M GT/PCI/SSE2 supported 1 NVIDIA GeForce 8600M +NVIDIA GeForce 8700 supported 3 NVIDIA GeForce 8700 +NVIDIA GeForce 8700M supported 3 NVIDIA GeForce 8700M +NVIDIA GeForce 8700M GT/PCI/SSE2 supported 3 NVIDIA GeForce 8700M +NVIDIA GeForce 8800 supported 3 NVIDIA GeForce 8800 +NVIDIA GeForce 8800 GS/PCI/SSE2 supported 3 NVIDIA GeForce 8800 +NVIDIA GeForce 8800 GT/PCI/SSE2 supported 3 NVIDIA GeForce 8800 +NVIDIA GeForce 8800 GT/PCI/SSE2/3DNOW! supported 3 NVIDIA GeForce 8800 +NVIDIA GeForce 8800 GTS 512/PCI/SSE2 supported 3 NVIDIA GeForce 8800 +NVIDIA GeForce 8800 GTS 512/PCI/SSE2/3DNOW! supported 3 NVIDIA GeForce 8800 +NVIDIA GeForce 8800 GTS/PCI/SSE2 supported 3 NVIDIA GeForce 8800 +NVIDIA GeForce 8800 GTS/PCI/SSE2/3DNOW! supported 3 NVIDIA GeForce 8800 +NVIDIA GeForce 8800 GTX/PCI/SSE2 supported 3 NVIDIA GeForce 8800 +NVIDIA GeForce 8800 Ultra/PCI/SSE2 supported 3 NVIDIA GeForce 8800 +NVIDIA GeForce 8800M GTS/PCI/SSE2 supported 3 NVIDIA GeForce 8800M +NVIDIA GeForce 8800M GTX/PCI/SSE2 supported 3 NVIDIA GeForce 8800M +NVIDIA GeForce 9100 supported 0 NVIDIA GeForce 9100 +NVIDIA GeForce 9100/PCI/SSE2 supported 0 NVIDIA GeForce 9100 +NVIDIA GeForce 9100/PCI/SSE2/3DNOW! supported 0 NVIDIA GeForce 9100 +NVIDIA GeForce 9100M supported 0 NVIDIA GeForce 9100M +NVIDIA GeForce 9100M G/PCI/SSE2 supported 0 NVIDIA GeForce 9100M +NVIDIA GeForce 9100M G/PCI/SSE2/3DNOW! supported 0 NVIDIA GeForce 9100M +NVIDIA GeForce 9200 supported 1 NVIDIA GeForce 9200 +NVIDIA GeForce 9200/PCI/SSE2 supported 1 NVIDIA GeForce 9200 +NVIDIA GeForce 9200/PCI/SSE2/3DNOW! supported 1 NVIDIA GeForce 9200 +NVIDIA GeForce 9200M GE/PCI/SSE2 supported 1 NVIDIA GeForce 9200M +NVIDIA GeForce 9200M GS/PCI/SSE2 supported 1 NVIDIA GeForce 9200M +NVIDIA GeForce 9300 supported 1 NVIDIA GeForce 9300 +NVIDIA GeForce 9300 / nForce 730i/PCI/SSE2 supported 1 NVIDIA GeForce 9300 +NVIDIA GeForce 9300 GE/PCI/SSE2 supported 1 NVIDIA GeForce 9300 +NVIDIA GeForce 9300 GE/PCI/SSE2/3DNOW! supported 1 NVIDIA GeForce 9300 +NVIDIA GeForce 9300 GS/PCI/SSE2 supported 1 NVIDIA GeForce 9300 +NVIDIA GeForce 9300 GS/PCI/SSE2/3DNOW! supported 1 NVIDIA GeForce 9300 +NVIDIA GeForce 9300 SE/PCI/SSE2 supported 1 NVIDIA GeForce 9300 +NVIDIA GeForce 9300M supported 1 NVIDIA GeForce 9300M +NVIDIA GeForce 9300M G/PCI/SSE2 supported 1 NVIDIA GeForce 9300M +NVIDIA GeForce 9300M G/PCI/SSE2/3DNOW! supported 1 NVIDIA GeForce 9300M +NVIDIA GeForce 9300M GS/PCI/SSE2 supported 1 NVIDIA GeForce 9300M +NVIDIA GeForce 9300M GS/PCI/SSE2/3DNOW! supported 1 NVIDIA GeForce 9300M +NVIDIA GeForce 9400 supported 1 NVIDIA GeForce 9400 +NVIDIA GeForce 9400 GT/PCI/SSE2 supported 1 NVIDIA GeForce 9400 +NVIDIA GeForce 9400 GT/PCI/SSE2/3DNOW! supported 1 NVIDIA GeForce 9400 +NVIDIA GeForce 9400/PCI/SSE2 supported 1 NVIDIA GeForce 9400 +NVIDIA GeForce 9400M supported 1 NVIDIA GeForce 9400M +NVIDIA GeForce 9400M G/PCI/SSE2 supported 1 NVIDIA GeForce 9400M +NVIDIA GeForce 9400M/PCI/SSE2 supported 1 NVIDIA GeForce 9400M +NVIDIA GeForce 9500 supported 2 NVIDIA GeForce 9500 +NVIDIA GeForce 9500 GS/PCI/SSE2 supported 2 NVIDIA GeForce 9500 +NVIDIA GeForce 9500 GS/PCI/SSE2/3DNOW! supported 2 NVIDIA GeForce 9500 +NVIDIA GeForce 9500 GT/PCI/SSE2 supported 2 NVIDIA GeForce 9500 +NVIDIA GeForce 9500 GT/PCI/SSE2/3DNOW! supported 2 NVIDIA GeForce 9500 +NVIDIA GeForce 9500M supported 2 NVIDIA GeForce 9500M +NVIDIA GeForce 9500M GS/PCI/SSE2 supported 2 NVIDIA GeForce 9500M +NVIDIA GeForce 9600 supported 2 NVIDIA GeForce 9600 +NVIDIA GeForce 9600 GS/PCI/SSE2 supported 2 NVIDIA GeForce 9600 +NVIDIA GeForce 9600 GSO 512/PCI/SSE2 supported 2 NVIDIA GeForce 9600 +NVIDIA GeForce 9600 GSO/PCI/SSE2 supported 2 NVIDIA GeForce 9600 +NVIDIA GeForce 9600 GSO/PCI/SSE2/3DNOW! supported 2 NVIDIA GeForce 9600 +NVIDIA GeForce 9600 GT/PCI/SSE2 supported 2 NVIDIA GeForce 9600 +NVIDIA GeForce 9600 GT/PCI/SSE2/3DNOW! supported 2 NVIDIA GeForce 9600 +NVIDIA GeForce 9600M supported 3 NVIDIA GeForce 9600M +NVIDIA GeForce 9600M GS/PCI/SSE2 supported 3 NVIDIA GeForce 9600M +NVIDIA GeForce 9600M GT/PCI/SSE2 supported 3 NVIDIA GeForce 9600M +NVIDIA GeForce 9650M GT/PCI/SSE2 supported 2 NVIDIA GeForce 9600 +NVIDIA GeForce 9700M supported 2 NVIDIA GeForce 9700M +NVIDIA GeForce 9700M GT/PCI/SSE2 supported 2 NVIDIA GeForce 9700M +NVIDIA GeForce 9700M GTS/PCI/SSE2 supported 2 NVIDIA GeForce 9700M +NVIDIA GeForce 9800 supported 3 NVIDIA GeForce 9800 +NVIDIA GeForce 9800 GT/PCI/SSE2 supported 3 NVIDIA GeForce 9800 +NVIDIA GeForce 9800 GT/PCI/SSE2/3DNOW! supported 3 NVIDIA GeForce 9800 +NVIDIA GeForce 9800 GTX+/PCI/SSE2 supported 3 NVIDIA GeForce 9800 +NVIDIA GeForce 9800 GTX+/PCI/SSE2/3DNOW! supported 3 NVIDIA GeForce 9800 +NVIDIA GeForce 9800 GTX/9800 GTX+/PCI/SSE2 supported 3 NVIDIA GeForce 9800 +NVIDIA GeForce 9800 GTX/PCI/SSE2 supported 3 NVIDIA GeForce 9800 +NVIDIA GeForce 9800 GX2/PCI/SSE2 supported 3 NVIDIA GeForce 9800 +NVIDIA GeForce 9800M supported 3 NVIDIA GeForce 9800M +NVIDIA GeForce 9800M GS/PCI/SSE2 supported 3 NVIDIA GeForce 9800M +NVIDIA GeForce 9800M GT/PCI/SSE2 supported 3 NVIDIA GeForce 9800M +NVIDIA GeForce 9800M GTS/PCI/SSE2 supported 3 NVIDIA GeForce 9800M +NVIDIA GeForce FX 5100 supported 0 NVIDIA GeForce FX 5100 +NVIDIA GeForce FX 5100/AGP/SSE/3DNOW! supported 0 NVIDIA GeForce FX 5100 +NVIDIA GeForce FX 5200 supported 0 NVIDIA GeForce FX 5200 +NVIDIA GeForce FX 5200/AGP/SSE supported 0 NVIDIA GeForce FX 5200 +NVIDIA GeForce FX 5200/AGP/SSE/3DNOW! supported 0 NVIDIA GeForce FX 5200 +NVIDIA GeForce FX 5200/AGP/SSE2 supported 0 NVIDIA GeForce FX 5200 +NVIDIA GeForce FX 5200/AGP/SSE2/3DNOW! supported 0 NVIDIA GeForce FX 5200 +NVIDIA GeForce FX 5200/PCI/SSE2 supported 0 NVIDIA GeForce FX 5200 +NVIDIA GeForce FX 5200/PCI/SSE2/3DNOW! supported 0 NVIDIA GeForce FX 5200 +NVIDIA GeForce FX 5200LE/AGP/SSE2 supported 0 NVIDIA GeForce FX 5200 +NVIDIA GeForce FX 5500 supported 0 NVIDIA GeForce FX 5500 +NVIDIA GeForce FX 5500/AGP/SSE/3DNOW! supported 0 NVIDIA GeForce FX 5500 +NVIDIA GeForce FX 5500/AGP/SSE2 supported 0 NVIDIA GeForce FX 5500 +NVIDIA GeForce FX 5500/AGP/SSE2/3DNOW! supported 0 NVIDIA GeForce FX 5500 +NVIDIA GeForce FX 5500/PCI/SSE2 supported 0 NVIDIA GeForce FX 5500 +NVIDIA GeForce FX 5500/PCI/SSE2/3DNOW! supported 0 NVIDIA GeForce FX 5500 +NVIDIA GeForce FX 5600 supported 0 NVIDIA GeForce FX 5600 +NVIDIA GeForce FX 5600/AGP/SSE2 supported 0 NVIDIA GeForce FX 5600 +NVIDIA GeForce FX 5600/AGP/SSE2/3DNOW! supported 0 NVIDIA GeForce FX 5600 +NVIDIA GeForce FX 5600XT/AGP/SSE2/3DNOW! supported 0 NVIDIA GeForce FX 5600 +NVIDIA GeForce FX 5700 supported 1 NVIDIA GeForce FX 5700 +NVIDIA GeForce FX 5700/AGP/SSE/3DNOW! supported 1 NVIDIA GeForce FX 5700 +NVIDIA GeForce FX 5700LE/AGP/SSE supported 1 NVIDIA GeForce FX 5700 +NVIDIA GeForce FX 5700LE/AGP/SSE/3DNOW! supported 1 NVIDIA GeForce FX 5700 +NVIDIA GeForce FX 5800 supported 1 NVIDIA GeForce FX 5800 +NVIDIA GeForce FX 5900 supported 1 NVIDIA GeForce FX 5900 +NVIDIA GeForce FX 5900/AGP/SSE2 supported 1 NVIDIA GeForce FX 5900 +NVIDIA GeForce FX 5900XT/AGP/SSE2 supported 1 NVIDIA GeForce FX 5900 +NVIDIA GeForce FX Go5100 supported 0 NVIDIA GeForce FX Go5100 +NVIDIA GeForce FX Go5100/AGP/SSE2 supported 0 NVIDIA GeForce FX Go5100 +NVIDIA GeForce FX Go5200 supported 0 NVIDIA GeForce FX Go5200 +NVIDIA GeForce FX Go5200/AGP/SSE2 supported 0 NVIDIA GeForce FX Go5200 +NVIDIA GeForce FX Go5300 supported 0 NVIDIA GeForce FX Go5300 +NVIDIA GeForce FX Go5600 supported 0 NVIDIA GeForce FX Go5600 +NVIDIA GeForce FX Go5600/AGP/SSE2 supported 0 NVIDIA GeForce FX Go5600 +NVIDIA GeForce FX Go5650/AGP/SSE2 supported 0 NVIDIA GeForce FX Go5600 +NVIDIA GeForce FX Go5700 supported 1 NVIDIA GeForce FX Go5700 +NVIDIA GeForce FX Go5xxx/AGP/SSE2 supported 0 NVIDIA GeForce FX Go5xxx +NVIDIA GeForce G 103M/PCI/SSE2 supported 0 NVIDIA G103M +NVIDIA GeForce G 105M/PCI/SSE2 supported 0 NVIDIA G105M +NVIDIA GeForce G 110M/PCI/SSE2 supported 0 NVIDIA G 110M +NVIDIA GeForce G100/PCI/SSE2 supported 0 NVIDIA G100 +NVIDIA GeForce G100/PCI/SSE2/3DNOW! supported 0 NVIDIA G100 +NVIDIA GeForce G102M/PCI/SSE2 supported 0 NVIDIA G102M +NVIDIA GeForce G105M/PCI/SSE2 supported 0 NVIDIA G105M +NVIDIA GeForce G200/PCI/SSE2 supported 0 NVIDIA G 200 +NVIDIA GeForce G205M/PCI/SSE2 supported 0 NVIDIA G 205M +NVIDIA GeForce G210/PCI/SSE2 supported 1 NVIDIA G 210 +NVIDIA GeForce G210/PCI/SSE2/3DNOW! supported 1 NVIDIA G 210 +NVIDIA GeForce G210M/PCI/SSE2 supported 1 NVIDIA G 210 +NVIDIA GeForce G310M/PCI/SSE2 supported 2 NVIDIA G 310M +NVIDIA GeForce GT 120/PCI/SSE2 supported 2 NVIDIA GT 120M +NVIDIA GeForce GT 120/PCI/SSE2/3DNOW! supported 2 NVIDIA GT 120M +NVIDIA GeForce GT 120M/PCI/SSE2 supported 2 NVIDIA GT 120M +NVIDIA GeForce GT 130M/PCI/SSE2 supported 2 NVIDIA GT 130M +NVIDIA GeForce GT 140/PCI/SSE2 supported 2 NVIDIA GT 140M +NVIDIA GeForce GT 220/PCI/SSE2 supported 2 NVIDIA GT 220M +NVIDIA GeForce GT 220/PCI/SSE2/3DNOW! supported 2 NVIDIA GT 220M +NVIDIA GeForce GT 220M/PCI/SSE2 supported 2 NVIDIA GT 220M +NVIDIA GeForce GT 230/PCI/SSE2 supported 2 NVIDIA GT 230M +NVIDIA GeForce GT 230M/PCI/SSE2 supported 2 NVIDIA GT 230M +NVIDIA GeForce GT 240 supported 2 NVIDIA GT 240M +NVIDIA GeForce GT 240/PCI/SSE2 supported 2 NVIDIA GT 240M +NVIDIA GeForce GT 240/PCI/SSE2/3DNOW! supported 2 NVIDIA GT 240M +NVIDIA GeForce GT 240M/PCI/SSE2 supported 2 NVIDIA GT 240M +NVIDIA GeForce GT 320/PCI/SSE2 supported 2 NVIDIA GT 320M +NVIDIA GeForce GT 320M/PCI/SSE2 supported 2 NVIDIA GT 320M +NVIDIA GeForce GT 325M/PCI/SSE2 supported 0 NVIDIA GT 325M +NVIDIA GeForce GT 330/PCI/SSE2 supported 3 NVIDIA GT 330M +NVIDIA GeForce GT 330/PCI/SSE2/3DNOW! supported 3 NVIDIA GT 330M +NVIDIA GeForce GT 330M/PCI/SSE2 supported 3 NVIDIA GT 330M +NVIDIA GeForce GT 335M/PCI/SSE2 supported 1 NVIDIA GT 335M +NVIDIA GeForce GT 340/PCI/SSE2 supported 2 NVIDIA GT 340M +NVIDIA GeForce GT 340/PCI/SSE2/3DNOW! supported 2 NVIDIA GT 340M +NVIDIA GeForce GT 415M/PCI/SSE2 supported 2 NVIDIA GT 415M +NVIDIA GeForce GT 420/PCI/SSE2 supported 2 NVIDIA GT 420M +NVIDIA GeForce GT 420M/PCI/SSE2 supported 2 NVIDIA GT 420M +NVIDIA GeForce GT 425M/PCI/SSE2 supported 3 NVIDIA GT 425M +NVIDIA GeForce GT 430/PCI/SSE2 supported 3 NVIDIA GT 430M +NVIDIA GeForce GT 430/PCI/SSE2/3DNOW! supported 3 NVIDIA GT 430M +NVIDIA GeForce GT 435M/PCI/SSE2 supported 3 NVIDIA GT 435M +NVIDIA GeForce GT 440/PCI/SSE2 supported 3 NVIDIA GT 440M +NVIDIA GeForce GT 440/PCI/SSE2/3DNOW! supported 3 NVIDIA GT 440M +NVIDIA GeForce GT 445M/PCI/SSE2 supported 3 NVIDIA GT 445M +NVIDIA GeForce GT 520M/PCI/SSE2 supported 3 NVIDIA GT 520M +NVIDIA GeForce GT 525M/PCI/SSE2 supported 3 NVIDIA GT 525M +NVIDIA GeForce GT 540M/PCI/SSE2 supported 3 NVIDIA GT 540M +NVIDIA GeForce GT 550M/PCI/SSE2 supported 3 NVIDIA GT 550M +NVIDIA GeForce GT 555M/PCI/SSE2 supported 3 NVIDIA GT 555M +NVIDIA GeForce GTS 150/PCI/SSE2 supported 2 NVIDIA GT 150M +NVIDIA GeForce GTS 160M/PCI/SSE2 supported 2 NVIDIA GTS 160M +NVIDIA GeForce GTS 240/PCI/SSE2 supported 3 NVIDIA GTS 240 +NVIDIA GeForce GTS 250/PCI/SSE2 supported 3 NVIDIA GTS 250 +NVIDIA GeForce GTS 250/PCI/SSE2/3DNOW! supported 3 NVIDIA GTS 250 +NVIDIA GeForce GTS 250M/PCI/SSE2 supported 3 NVIDIA GTS 250 +NVIDIA GeForce GTS 350M/PCI/SSE2 supported 3 NVIDIA GTS 350M +NVIDIA GeForce GTS 360M/PCI/SSE2 supported 3 NVIDIA GTS 360M +NVIDIA GeForce GTS 450/PCI/SSE2 supported 3 NVIDIA GTS 450 +NVIDIA GeForce GTS 450/PCI/SSE2/3DNOW! supported 3 NVIDIA GTS 450 +NVIDIA GeForce GTS 455/PCI/SSE2 supported 3 NVIDIA GTS 450 +NVIDIA GeForce GTX 260/PCI/SSE2 supported 3 NVIDIA GTX 260 +NVIDIA GeForce GTX 260/PCI/SSE2/3DNOW! supported 3 NVIDIA GTX 260 +NVIDIA GeForce GTX 260M/PCI/SSE2 supported 3 NVIDIA GTX 260 +NVIDIA GeForce GTX 275/PCI/SSE2 supported 3 NVIDIA GTX 275 +NVIDIA GeForce GTX 280 supported 3 NVIDIA GTX 280 +NVIDIA GeForce GTX 280/PCI/SSE2 supported 3 NVIDIA GTX 280 +NVIDIA GeForce GTX 280M/PCI/SSE2 supported 3 NVIDIA GTX 280 +NVIDIA GeForce GTX 285/PCI/SSE2 supported 3 NVIDIA GTX 285 +NVIDIA GeForce GTX 295/PCI/SSE2 supported 3 NVIDIA GTX 295 +NVIDIA GeForce GTX 460 SE/PCI/SSE2 supported 3 NVIDIA GTX 460 +NVIDIA GeForce GTX 460 SE/PCI/SSE2/3DNOW! supported 3 NVIDIA GTX 460 +NVIDIA GeForce GTX 460/PCI/SSE2 supported 3 NVIDIA GTX 460 +NVIDIA GeForce GTX 460/PCI/SSE2/3DNOW! supported 3 NVIDIA GTX 460 +NVIDIA GeForce GTX 460M/PCI/SSE2 supported 3 NVIDIA GTX 460M +NVIDIA GeForce GTX 465/PCI/SSE2 supported 3 NVIDIA GTX 465 +NVIDIA GeForce GTX 465/PCI/SSE2/3DNOW! supported 3 NVIDIA GTX 465 +NVIDIA GeForce GTX 470/PCI/SSE2 supported 3 NVIDIA GTX 470 +NVIDIA GeForce GTX 470/PCI/SSE2/3DNOW! supported 3 NVIDIA GTX 470 +NVIDIA GeForce GTX 480/PCI/SSE2 supported 3 NVIDIA GTX 480 +NVIDIA GeForce GTX 550 Ti/PCI/SSE2 supported 3 NVIDIA GTX 550 +NVIDIA GeForce GTX 550 Ti/PCI/SSE2/3DNOW! supported 3 NVIDIA GTX 550 +NVIDIA GeForce GTX 560 Ti/PCI/SSE2 supported 3 NVIDIA GTX 560 +NVIDIA GeForce GTX 560 Ti/PCI/SSE2/3DNOW! supported 3 NVIDIA GTX 560 +NVIDIA GeForce GTX 560/PCI/SSE2 supported 3 NVIDIA GTX 560 +NVIDIA GeForce GTX 570/PCI/SSE2 supported 3 NVIDIA GTX 570 +NVIDIA GeForce GTX 570/PCI/SSE2/3DNOW! supported 3 NVIDIA GTX 570 +NVIDIA GeForce GTX 580/PCI/SSE2 supported 3 NVIDIA GTX 580 +NVIDIA GeForce GTX 580/PCI/SSE2/3DNOW! supported 3 NVIDIA GTX 580 +NVIDIA GeForce GTX 580M/PCI/SSE2 supported 3 NVIDIA GTX 580M +NVIDIA GeForce GTX 590/PCI/SSE2 supported 3 NVIDIA GTX 590 +NVIDIA GeForce Go 6 supported 1 NVIDIA GeForce Go 6 +NVIDIA GeForce Go 6100 supported 0 NVIDIA GeForce Go 6100 +NVIDIA GeForce Go 6100/PCI/SSE2 supported 0 NVIDIA GeForce Go 6100 +NVIDIA GeForce Go 6100/PCI/SSE2/3DNOW! supported 0 NVIDIA GeForce Go 6100 +NVIDIA GeForce Go 6150/PCI/SSE2 supported 0 NVIDIA GeForce Go 6100 +NVIDIA GeForce Go 6150/PCI/SSE2/3DNOW! supported 0 NVIDIA GeForce Go 6100 +NVIDIA GeForce Go 6200 supported 0 NVIDIA GeForce Go 6200 +NVIDIA GeForce Go 6200/PCI/SSE2 supported 0 NVIDIA GeForce Go 6200 +NVIDIA GeForce Go 6400 supported 1 NVIDIA GeForce Go 6400 +NVIDIA GeForce Go 6400/PCI/SSE2 supported 1 NVIDIA GeForce Go 6400 +NVIDIA GeForce Go 6600 supported 1 NVIDIA GeForce Go 6600 +NVIDIA GeForce Go 6600/PCI/SSE2 supported 1 NVIDIA GeForce Go 6600 +NVIDIA GeForce Go 6800 supported 1 NVIDIA GeForce Go 6800 +NVIDIA GeForce Go 6800 Ultra/PCI/SSE2 supported 1 NVIDIA GeForce Go 6800 +NVIDIA GeForce Go 6800/PCI/SSE2 supported 1 NVIDIA GeForce Go 6800 +NVIDIA GeForce Go 7200 supported 1 NVIDIA GeForce Go 7200 +NVIDIA GeForce Go 7200/PCI/SSE2 supported 1 NVIDIA GeForce Go 7200 +NVIDIA GeForce Go 7200/PCI/SSE2/3DNOW! supported 1 NVIDIA GeForce Go 7200 +NVIDIA GeForce Go 7300 supported 1 NVIDIA GeForce Go 7300 +NVIDIA GeForce Go 7300/PCI/SSE2 supported 1 NVIDIA GeForce Go 7300 +NVIDIA GeForce Go 7300/PCI/SSE2/3DNOW! supported 1 NVIDIA GeForce Go 7300 +NVIDIA GeForce Go 7400 supported 1 NVIDIA GeForce Go 7400 +NVIDIA GeForce Go 7400/PCI/SSE2 supported 1 NVIDIA GeForce Go 7400 +NVIDIA GeForce Go 7400/PCI/SSE2/3DNOW! supported 1 NVIDIA GeForce Go 7400 +NVIDIA GeForce Go 7600 supported 2 NVIDIA GeForce Go 7600 +NVIDIA GeForce Go 7600/PCI/SSE2 supported 2 NVIDIA GeForce Go 7600 +NVIDIA GeForce Go 7600/PCI/SSE2/3DNOW! supported 2 NVIDIA GeForce Go 7600 +NVIDIA GeForce Go 7700 supported 2 NVIDIA GeForce Go 7700 +NVIDIA GeForce Go 7800 supported 2 NVIDIA GeForce Go 7800 +NVIDIA GeForce Go 7800 GTX/PCI/SSE2 supported 2 NVIDIA GeForce Go 7800 +NVIDIA GeForce Go 7900 supported 2 NVIDIA GeForce Go 7900 +NVIDIA GeForce Go 7900 GS/PCI/SSE2 supported 2 NVIDIA GeForce Go 7900 +NVIDIA GeForce Go 7900 GTX/PCI/SSE2 supported 2 NVIDIA GeForce Go 7900 +NVIDIA GeForce Go 7950 GTX/PCI/SSE2 supported 2 NVIDIA GeForce Go 7900 +NVIDIA GeForce PCX supported 0 NVIDIA GeForce PCX +NVIDIA GeForce2 GTS/AGP/SSE supported 0 NVIDIA GeForce 2 +NVIDIA GeForce2 MX/AGP/3DNOW! supported 0 NVIDIA GeForce 2 +NVIDIA GeForce2 MX/AGP/SSE/3DNOW! supported 0 NVIDIA GeForce 2 +NVIDIA GeForce2 MX/AGP/SSE2 supported 0 NVIDIA GeForce 2 +NVIDIA GeForce2 MX/PCI/SSE2 supported 0 NVIDIA GeForce 2 +NVIDIA GeForce3/AGP/SSE/3DNOW! supported 0 NVIDIA GeForce 3 +NVIDIA GeForce3/AGP/SSE2 supported 0 NVIDIA GeForce 3 +NVIDIA GeForce4 420 Go 32M/AGP/SSE2 supported 0 NVIDIA GeForce 4 +NVIDIA GeForce4 420 Go 32M/AGP/SSE2/3DNOW! supported 0 NVIDIA GeForce 4 +NVIDIA GeForce4 420 Go 32M/PCI/SSE2/3DNOW! supported 0 NVIDIA GeForce 4 +NVIDIA GeForce4 440 Go 64M/AGP/SSE2/3DNOW! supported 0 NVIDIA GeForce 4 +NVIDIA GeForce4 460 Go/AGP/SSE2 supported 0 NVIDIA GeForce 4 +NVIDIA GeForce4 MX 4000/AGP/SSE/3DNOW! supported 0 NVIDIA GeForce 4 +NVIDIA GeForce4 MX 4000/AGP/SSE2 supported 0 NVIDIA GeForce 4 +NVIDIA GeForce4 MX 4000/PCI/3DNOW! supported 0 NVIDIA GeForce 4 +NVIDIA GeForce4 MX 4000/PCI/SSE/3DNOW! supported 0 NVIDIA GeForce 4 +NVIDIA GeForce4 MX 4000/PCI/SSE2 supported 0 NVIDIA GeForce 4 +NVIDIA GeForce4 MX 420/AGP/SSE/3DNOW! supported 0 NVIDIA GeForce 4 +NVIDIA GeForce4 MX 420/AGP/SSE2 supported 0 NVIDIA GeForce 4 +NVIDIA GeForce4 MX 440 with AGP8X/AGP/SSE2 supported 0 NVIDIA GeForce 4 +NVIDIA GeForce4 MX 440/AGP/SSE2 supported 0 NVIDIA GeForce 4 +NVIDIA GeForce4 MX 440/AGP/SSE2/3DNOW! supported 0 NVIDIA GeForce 4 +NVIDIA GeForce4 MX 440SE with AGP8X/AGP/SSE2 supported 0 NVIDIA GeForce 4 +NVIDIA GeForce4 MX Integrated GPU/AGP/SSE/3DNOW! supported 0 NVIDIA GeForce 4 +NVIDIA GeForce4 Ti 4200 with AGP8X/AGP/SSE supported 0 NVIDIA GeForce 4 +NVIDIA GeForce4 Ti 4200/AGP/SSE/3DNOW! supported 0 NVIDIA GeForce 4 +NVIDIA GeForce4 Ti 4400/AGP/SSE2 supported 0 NVIDIA GeForce 4 +NVIDIA Generic UNRECOGNIZED +NVIDIA ION LE/PCI/SSE2 supported 2 NVIDIA ION +NVIDIA ION/PCI/SSE2 supported 2 NVIDIA ION +NVIDIA ION/PCI/SSE2/3DNOW! supported 2 NVIDIA ION +NVIDIA MCP61/PCI/SSE2 UNRECOGNIZED +NVIDIA MCP61/PCI/SSE2/3DNOW! UNRECOGNIZED +NVIDIA MCP73/PCI/SSE2 UNRECOGNIZED +NVIDIA MCP79MH/PCI/SSE2 UNRECOGNIZED +NVIDIA MCP79MX/PCI/SSE2 UNRECOGNIZED +NVIDIA MCP7A-O/PCI/SSE2 UNRECOGNIZED +NVIDIA MCP7A-S/PCI/SSE2 UNRECOGNIZED +NVIDIA MCP89-EPT/PCI/SSE2 UNRECOGNIZED +NVIDIA N10M-GE1/PCI/SSE2 UNRECOGNIZED +NVIDIA N10P-GE1/PCI/SSE2 UNRECOGNIZED +NVIDIA N10P-GV2/PCI/SSE2 UNRECOGNIZED +NVIDIA N11M-GE1/PCI/SSE2 UNRECOGNIZED +NVIDIA N11M-GE2/PCI/SSE2 UNRECOGNIZED +NVIDIA N12E-GS-A1/PCI/SSE2 UNRECOGNIZED +NVIDIA NB9M-GE/PCI/SSE2 UNRECOGNIZED +NVIDIA NB9M-GE1/PCI/SSE2 UNRECOGNIZED +NVIDIA NB9M-GS/PCI/SSE2 UNRECOGNIZED +NVIDIA NB9M-NS/PCI/SSE2 UNRECOGNIZED +NVIDIA NB9P-GE1/PCI/SSE2 UNRECOGNIZED +NVIDIA NB9P-GS/PCI/SSE2 UNRECOGNIZED +NVIDIA NV17/AGP/3DNOW! UNRECOGNIZED +NVIDIA NV17/AGP/SSE2 UNRECOGNIZED +NVIDIA NV34 supported 0 NVIDIA NV34 +NVIDIA NV35 supported 0 NVIDIA NV35 +NVIDIA NV36/AGP/SSE/3DNOW! UNRECOGNIZED +NVIDIA NV36/AGP/SSE2 UNRECOGNIZED +NVIDIA NV41/PCI/SSE2 UNRECOGNIZED +NVIDIA NV43 supported 1 NVIDIA NV43 +NVIDIA NV44 supported 1 NVIDIA NV44 +NVIDIA NVIDIA GeForce 210 OpenGL Engine supported 2 NVIDIA 210 +NVIDIA NVIDIA GeForce 320M OpenGL Engine supported 2 NVIDIA 320M +NVIDIA NVIDIA GeForce 7300 GT OpenGL Engine supported 1 NVIDIA GeForce 7300 +NVIDIA NVIDIA GeForce 7600 GT OpenGL Engine supported 2 NVIDIA GeForce 7600 +NVIDIA NVIDIA GeForce 8600M GT OpenGL Engine supported 1 NVIDIA GeForce 8600M +NVIDIA NVIDIA GeForce 8800 GS OpenGL Engine supported 3 NVIDIA GeForce 8800 +NVIDIA NVIDIA GeForce 8800 GT OpenGL Engine supported 3 NVIDIA GeForce 8800 +NVIDIA NVIDIA GeForce 9400 OpenGL Engine supported 1 NVIDIA GeForce 9400 +NVIDIA NVIDIA GeForce 9400M OpenGL Engine supported 1 NVIDIA GeForce 9400M +NVIDIA NVIDIA GeForce 9500 GT OpenGL Engine supported 2 NVIDIA GeForce 9500 +NVIDIA NVIDIA GeForce 9600M GT OpenGL Engine supported 3 NVIDIA GeForce 9600M +NVIDIA NVIDIA GeForce GT 120 OpenGL Engine supported 2 NVIDIA GT 120M +NVIDIA NVIDIA GeForce GT 130 OpenGL Engine supported 2 NVIDIA GT 130M +NVIDIA NVIDIA GeForce GT 220 OpenGL Engine supported 2 NVIDIA GT 220M +NVIDIA NVIDIA GeForce GT 230M OpenGL Engine supported 2 NVIDIA GT 230M +NVIDIA NVIDIA GeForce GT 240M OpenGL Engine supported 2 NVIDIA GT 240M +NVIDIA NVIDIA GeForce GT 330M OpenGL Engine supported 3 NVIDIA GT 330M +NVIDIA NVIDIA GeForce GT 420M OpenGL Engine supported 2 NVIDIA GT 420M +NVIDIA NVIDIA GeForce GT 425M OpenGL Engine supported 3 NVIDIA GT 425M +NVIDIA NVIDIA GeForce GT 430 OpenGL Engine supported 3 NVIDIA GT 430M +NVIDIA NVIDIA GeForce GT 440 OpenGL Engine supported 3 NVIDIA GT 440M +NVIDIA NVIDIA GeForce GT 540M OpenGL Engine supported 3 NVIDIA GT 540M +NVIDIA NVIDIA GeForce GTS 240 OpenGL Engine supported 3 NVIDIA GTS 240 +NVIDIA NVIDIA GeForce GTS 250 OpenGL Engine supported 3 NVIDIA GTS 250 +NVIDIA NVIDIA GeForce GTS 450 OpenGL Engine supported 3 NVIDIA GTS 450 +NVIDIA NVIDIA GeForce GTX 285 OpenGL Engine supported 3 NVIDIA GTX 285 +NVIDIA NVIDIA GeForce GTX 460 OpenGL Engine supported 3 NVIDIA GTX 460 +NVIDIA NVIDIA GeForce GTX 460M OpenGL Engine supported 3 NVIDIA GTX 460M +NVIDIA NVIDIA GeForce GTX 465 OpenGL Engine supported 3 NVIDIA GTX 465 +NVIDIA NVIDIA GeForce GTX 470 OpenGL Engine supported 3 NVIDIA GTX 470 +NVIDIA NVIDIA GeForce GTX 480 OpenGL Engine supported 3 NVIDIA GTX 480 +NVIDIA NVIDIA GeForce Pre-Release ION OpenGL Engine UNRECOGNIZED +NVIDIA NVIDIA GeForce4 OpenGL Engine supported 0 NVIDIA GeForce 4 +NVIDIA NVIDIA NV34MAP OpenGL Engine supported 0 NVIDIA NV34 +NVIDIA NVIDIA Quadro 4000 OpenGL Engine supported 3 NVIDIA Quadro 4000 +NVIDIA NVIDIA Quadro FX 4800 OpenGL Engine supported 3 NVIDIA Quadro FX 4800 +NVIDIA NVS 2100M/PCI/SSE2 supported 2 NVIDIA Quadro NVS 2100M +NVIDIA NVS 300/PCI/SSE2 supported 0 NVIDIA Quadro NVS +NVIDIA NVS 3100M/PCI/SSE2 supported 2 NVIDIA Quadro NVS 3100M +NVIDIA NVS 4100/PCI/SSE2/3DNOW! supported 0 NVIDIA Quadro NVS +NVIDIA NVS 4200M/PCI/SSE2 supported 2 NVIDIA Quadro NVS 4200M +NVIDIA NVS 5100M/PCI/SSE2 supported 2 NVIDIA Quadro NVS 5100M +NVIDIA PCI UNRECOGNIZED +NVIDIA Quadro 2000/PCI/SSE2 supported 3 NVIDIA Quadro 2000 M/D +NVIDIA Quadro 4000 supported 3 NVIDIA Quadro 4000 +NVIDIA Quadro 4000 OpenGL Engine supported 3 NVIDIA Quadro 4000 +NVIDIA Quadro 4000/PCI/SSE2 supported 3 NVIDIA Quadro 4000 +NVIDIA Quadro 5000/PCI/SSE2 supported 3 NVIDIA Quadro 50x0 M +NVIDIA Quadro 5000M/PCI/SSE2 supported 3 NVIDIA Quadro 50x0 M +NVIDIA Quadro 600 supported 2 NVIDIA Quadro 600 +NVIDIA Quadro 600/PCI/SSE2 supported 2 NVIDIA Quadro 600 +NVIDIA Quadro 600/PCI/SSE2/3DNOW! supported 2 NVIDIA Quadro 600 +NVIDIA Quadro 6000 supported 3 NVIDIA Quadro 6000 +NVIDIA Quadro 6000/PCI/SSE2 supported 3 NVIDIA Quadro 6000 +NVIDIA Quadro CX/PCI/SSE2 UNRECOGNIZED +NVIDIA Quadro DCC supported 0 NVIDIA Quadro DCC +NVIDIA Quadro FX supported 1 NVIDIA Quadro FX +NVIDIA Quadro FX 1100/AGP/SSE2 supported 1 NVIDIA Quadro FX +NVIDIA Quadro FX 1400/PCI/SSE2 supported 2 NVIDIA Quadro 400 +NVIDIA Quadro FX 1500 supported 1 NVIDIA Quadro FX +NVIDIA Quadro FX 1500M/PCI/SSE2 supported 1 NVIDIA Quadro FX 1500M +NVIDIA Quadro FX 1600M/PCI/SSE2 supported 2 NVIDIA Quadro 600 +NVIDIA Quadro FX 1700 supported 1 NVIDIA Quadro FX +NVIDIA Quadro FX 1700M/PCI/SSE2 supported 1 NVIDIA Quadro FX +NVIDIA Quadro FX 1800 supported 1 NVIDIA Quadro FX +NVIDIA Quadro FX 1800/PCI/SSE2 supported 1 NVIDIA Quadro FX +NVIDIA Quadro FX 1800M/PCI/SSE2 supported 1 NVIDIA Quadro FX +NVIDIA Quadro FX 2500M/PCI/SSE2 supported 2 NVIDIA Quadro FX 2500M +NVIDIA Quadro FX 2700M/PCI/SSE2 supported 3 NVIDIA Quadro FX 2700M +NVIDIA Quadro FX 2800M/PCI/SSE2 supported 3 NVIDIA Quadro FX 2800M +NVIDIA Quadro FX 3400 supported 2 NVIDIA Quadro 400 +NVIDIA Quadro FX 3450 supported 1 NVIDIA Quadro FX +NVIDIA Quadro FX 3450/4000 SDI/PCI/SSE2 supported 2 NVIDIA Quadro 400 +NVIDIA Quadro FX 3500 supported 2 NVIDIA Quadro FX 3500 +NVIDIA Quadro FX 3500M/PCI/SSE2 supported 2 NVIDIA Quadro FX 3500 +NVIDIA Quadro FX 360M/PCI/SSE2 supported 1 NVIDIA Quadro FX +NVIDIA Quadro FX 370 supported 1 NVIDIA Quadro FX +NVIDIA Quadro FX 370/PCI/SSE2 supported 1 NVIDIA Quadro FX +NVIDIA Quadro FX 3700 supported 3 NVIDIA Quadro FX 3700 +NVIDIA Quadro FX 3700M/PCI/SSE2 supported 3 NVIDIA Quadro FX 3700 +NVIDIA Quadro FX 370M/PCI/SSE2 supported 1 NVIDIA Quadro FX +NVIDIA Quadro FX 3800 supported 3 NVIDIA Quadro FX 3800 +NVIDIA Quadro FX 3800M/PCI/SSE2 supported 3 NVIDIA Quadro FX 3800 +NVIDIA Quadro FX 4500 supported 3 NVIDIA Quadro FX 4500 +NVIDIA Quadro FX 4600 supported 2 NVIDIA Quadro 600 +NVIDIA Quadro FX 4800 supported 3 NVIDIA Quadro FX 4800 +NVIDIA Quadro FX 4800/PCI/SSE2 supported 3 NVIDIA Quadro FX 4800 +NVIDIA Quadro FX 560 supported 1 NVIDIA Quadro FX +NVIDIA Quadro FX 5600 supported 2 NVIDIA Quadro 600 +NVIDIA Quadro FX 570 supported 1 NVIDIA Quadro FX +NVIDIA Quadro FX 570/PCI/SSE2 supported 1 NVIDIA Quadro FX +NVIDIA Quadro FX 570M/PCI/SSE2 supported 1 NVIDIA Quadro FX +NVIDIA Quadro FX 580/PCI/SSE2 supported 1 NVIDIA Quadro FX +NVIDIA Quadro FX 770M/PCI/SSE2 supported 2 NVIDIA Quadro FX 770M +NVIDIA Quadro FX 880M supported 3 NVIDIA Quadro FX 880M +NVIDIA Quadro FX 880M/PCI/SSE2 supported 3 NVIDIA Quadro FX 880M +NVIDIA Quadro FX Go700/AGP/SSE2 supported 1 NVIDIA Quadro FX +NVIDIA Quadro NVS supported 0 NVIDIA Quadro NVS +NVIDIA Quadro NVS 110M/PCI/SSE2 supported 0 NVIDIA Quadro NVS 1xxM +NVIDIA Quadro NVS 130M/PCI/SSE2 supported 0 NVIDIA Quadro NVS 1xxM +NVIDIA Quadro NVS 135M/PCI/SSE2 supported 0 NVIDIA Quadro NVS 1xxM +NVIDIA Quadro NVS 140M/PCI/SSE2 supported 0 NVIDIA Quadro NVS 1xxM +NVIDIA Quadro NVS 150M/PCI/SSE2 supported 0 NVIDIA Quadro NVS 1xxM +NVIDIA Quadro NVS 160M/PCI/SSE2 supported 0 NVIDIA Quadro NVS 1xxM +NVIDIA Quadro NVS 210S/PCI/SSE2/3DNOW! supported 0 NVIDIA Quadro NVS +NVIDIA Quadro NVS 285/PCI/SSE2 supported 0 NVIDIA Quadro NVS +NVIDIA Quadro NVS 290/PCI/SSE2 supported 0 NVIDIA Quadro NVS +NVIDIA Quadro NVS 295/PCI/SSE2 supported 0 NVIDIA Quadro NVS +NVIDIA Quadro NVS 320M/PCI/SSE2 supported 2 NVIDIA Quadro NVS 320M +NVIDIA Quadro NVS 55/280 PCI/PCI/SSE2 supported 0 NVIDIA Quadro NVS +NVIDIA Quadro NVS/PCI/SSE2 supported 0 NVIDIA Quadro NVS +NVIDIA Quadro PCI-E Series/PCI/SSE2/3DNOW! UNRECOGNIZED +NVIDIA Quadro VX 200/PCI/SSE2 UNRECOGNIZED +NVIDIA Quadro/AGP/SSE2 UNRECOGNIZED +NVIDIA Quadro2 supported 0 NVIDIA Quadro2 +NVIDIA Quadro4 supported 0 NVIDIA Quadro4 +NVIDIA RIVA TNT unsupported 0 NVIDIA RIVA TNT +NVIDIA RIVA TNT2/AGP/SSE2 unsupported 0 NVIDIA RIVA TNT +NVIDIA RIVA TNT2/PCI/3DNOW! unsupported 0 NVIDIA RIVA TNT +NVIDIA nForce unsupported 0 NVIDIA nForce +NVIDIA unknown board/AGP/SSE2 UNRECOGNIZED +NVIDIA unknown board/PCI/SSE2 UNRECOGNIZED +NVIDIA unknown board/PCI/SSE2/3DNOW! UNRECOGNIZED +Parallels and ATI Technologies Inc. Parallels using ATI Radeon HD 5670 OpenGL Engine supported 3 ATI Radeon HD 5600 +Parallels and ATI Technologies Inc. Parallels using ATI Radeon HD 5750 OpenGL Engine supported 3 ATI Radeon HD 5700 +Parallels and ATI Technologies Inc. Parallels using ATI Radeon HD 5770 OpenGL Engine supported 3 ATI Radeon HD 5700 +Parallels and ATI Technologies Inc. Parallels using ATI Radeon HD 6490M OpenGL Engine supported 3 ATI Radeon HD 6400 +Parallels and ATI Technologies Inc. Parallels using ATI Radeon HD 6750M OpenGL Engine supported 3 ATI Radeon HD 6700 +Parallels and Intel Inc. 3D-Analyze v2.3 - http://www.tommti-systems.com UNRECOGNIZED +Parallels and Intel Inc. Parallels using Intel HD Graphics 3000 OpenGL Engine supported 2 Intel HD Graphics +Parallels and NVIDIA Parallels using NVIDIA GeForce 320M OpenGL Engine supported 2 NVIDIA 320M +Parallels and NVIDIA Parallels using NVIDIA GeForce 9400 OpenGL Engine supported 1 NVIDIA GeForce 9400 +Parallels and NVIDIA Parallels using NVIDIA GeForce GT 120 OpenGL Engine supported 2 NVIDIA GT 120M +Parallels and NVIDIA Parallels using NVIDIA GeForce GT 330M OpenGL Engine supported 3 NVIDIA GT 330M +Radeon RV350 on Gallium supported 0 ATI RV350 (9600) +S3 UNRECOGNIZED +S3 Graphics VIA/S3G UniChrome IGP/MMX/K3D unsupported 0 S3 +S3 Graphics VIA/S3G UniChrome Pro IGP/MMX/SSE unsupported 0 S3 +S3 Graphics, Incorporated ProSavage/Twister unsupported 0 S3 +S3 Graphics, Incorporated S3 Graphics Chrome9 HC unsupported 0 S3 +S3 Graphics, Incorporated S3 Graphics DeltaChrome unsupported 0 S3 +S3 Graphics, Incorporated VIA Chrome9 HC IGP unsupported 0 S3 +SiS unsupported 0 SiS +SiS 661 VGA unsupported 0 SiS +SiS 662 VGA unsupported 0 SiS +SiS 741 VGA unsupported 0 SiS +SiS 760 VGA unsupported 0 SiS +SiS 761GX VGA unsupported 0 SiS +SiS Mirage Graphics3 unsupported 0 SiS +Trident unsupported 0 Trident +Tungsten Graphics unsupported 0 Tungsten Graphics +Tungsten Graphics, Inc Mesa DRI 865G GEM 20091221 2009Q4 x86/MMX/SSE2 unsupported 0 Mesa +Tungsten Graphics, Inc Mesa DRI 865G GEM 20100330 DEVELOPMENT x86/MMX/SSE2 unsupported 0 Mesa +Tungsten Graphics, Inc Mesa DRI 915G GEM 20091221 2009Q4 x86/MMX/SSE2 unsupported 0 Mesa +Tungsten Graphics, Inc Mesa DRI 915G GEM 20100330 DEVELOPMENT x86/MMX/SSE2 unsupported 0 Mesa +Tungsten Graphics, Inc Mesa DRI 915GM GEM 20090712 2009Q2 RC3 x86/MMX/SSE2 unsupported 0 Mesa +Tungsten Graphics, Inc Mesa DRI 915GM GEM 20091221 2009Q4 x86/MMX/SSE2 unsupported 0 Mesa +Tungsten Graphics, Inc Mesa DRI 915GM GEM 20100330 DEVELOPMENT x86/MMX/SSE2 unsupported 0 Mesa +Tungsten Graphics, Inc Mesa DRI 945G unsupported 0 Mesa +Tungsten Graphics, Inc Mesa DRI 945G GEM 20091221 2009Q4 x86/MMX/SSE2 unsupported 0 Mesa +Tungsten Graphics, Inc Mesa DRI 945G GEM 20100330 DEVELOPMENT unsupported 0 Mesa +Tungsten Graphics, Inc Mesa DRI 945G GEM 20100330 DEVELOPMENT x86/MMX/SSE2 unsupported 0 Mesa +Tungsten Graphics, Inc Mesa DRI 945GM GEM 20090712 2009Q2 RC3 x86/MMX/SSE2 unsupported 0 Mesa +Tungsten Graphics, Inc Mesa DRI 945GM GEM 20091221 2009Q4 x86/MMX/SSE2 unsupported 0 Mesa +Tungsten Graphics, Inc Mesa DRI 945GM GEM 20100328 2010Q1 x86/MMX/SSE2 unsupported 0 Mesa +Tungsten Graphics, Inc Mesa DRI 945GM GEM 20100330 DEVELOPMENT x86/MMX/SSE2 unsupported 0 Mesa +Tungsten Graphics, Inc Mesa DRI 945GME x86/MMX/SSE2 unsupported 0 Mesa +Tungsten Graphics, Inc Mesa DRI 945GME 20061017 unsupported 0 Mesa +Tungsten Graphics, Inc Mesa DRI 945GME GEM 20090712 2009Q2 RC3 x86/MMX/SSE2 unsupported 0 Mesa +Tungsten Graphics, Inc Mesa DRI 945GME GEM 20091221 2009Q4 x86/MMX/SSE2 unsupported 0 Mesa +Tungsten Graphics, Inc Mesa DRI 945GME GEM 20100330 DEVELOPMENT x86/MMX/SSE2 unsupported 0 Mesa +Tungsten Graphics, Inc Mesa DRI 965GM GEM 20090326 2009Q1 RC2 x86/MMX/SSE2 unsupported 0 Mesa +Tungsten Graphics, Inc Mesa DRI 965GM GEM 20090712 2009Q2 RC3 x86/MMX/SSE2 unsupported 0 Mesa +Tungsten Graphics, Inc Mesa DRI 965GM GEM 20091221 2009Q4 x86/MMX/SSE2 unsupported 0 Mesa +Tungsten Graphics, Inc Mesa DRI 965GM GEM 20100330 DEVELOPMENT x86/MMX/SSE2 unsupported 0 Mesa +Tungsten Graphics, Inc Mesa DRI G33 20061017 x86/MMX/SSE2 unsupported 0 Mesa +Tungsten Graphics, Inc Mesa DRI G33 GEM 20090712 2009Q2 RC3 x86/MMX/SSE2 unsupported 0 Mesa +Tungsten Graphics, Inc Mesa DRI G33 GEM 20091221 2009Q4 x86/MMX/SSE2 unsupported 0 Mesa +Tungsten Graphics, Inc Mesa DRI G41 GEM 20091221 2009Q4 x86/MMX/SSE2 unsupported 0 Mesa +Tungsten Graphics, Inc Mesa DRI G41 GEM 20100330 DEVELOPMENT x86/MMX/SSE2 unsupported 0 Mesa +Tungsten Graphics, Inc Mesa DRI GMA500 20081116 - 5.0.1.0046 x86/MMX/SSE2 unsupported 0 Mesa +Tungsten Graphics, Inc Mesa DRI IGD GEM 20091221 2009Q4 x86/MMX/SSE2 unsupported 0 Mesa +Tungsten Graphics, Inc Mesa DRI IGD GEM 20100330 DEVELOPMENT unsupported 0 Mesa +Tungsten Graphics, Inc Mesa DRI IGD GEM 20100330 DEVELOPMENT x86/MMX/SSE2 unsupported 0 Mesa +Tungsten Graphics, Inc Mesa DRI IGDNG_D GEM 20091221 2009Q4 x86/MMX/SSE2 unsupported 0 Mesa +Tungsten Graphics, Inc Mesa DRI Ironlake Desktop GEM 20100330 DEVELOPMENT x86/MMX/SSE2 unsupported 0 Mesa +Tungsten Graphics, Inc Mesa DRI Ironlake Mobile GEM 20100330 DEVELOPMENT x86/MMX/SSE2 unsupported 0 Mesa +Tungsten Graphics, Inc Mesa DRI Mobile Intelå¨ GM45 Express Chipset 20080716 x86/MMX/SSE2 unsupported 0 Mesa +Tungsten Graphics, Inc Mesa DRI Mobile Intelå¨ GM45 Express Chipset GEM 20090712 2009Q2 RC3 x86/MMX... unsupported 0 Mesa +Tungsten Graphics, Inc Mesa DRI Mobile Intelå¨ GM45 Express Chipset GEM 20091221 2009Q4 x86/MMX/SSE2 unsupported 0 Mesa +Tungsten Graphics, Inc Mesa DRI Mobile Intelå¨ GM45 Express Chipset GEM 20100328 2010Q1 unsupported 0 Mesa +Tungsten Graphics, Inc Mesa DRI Mobile Intelå¨ GM45 Express Chipset GEM 20100330 DEVELOPMENT unsupported 0 Mesa +Tungsten Graphics, Inc Mesa DRI Mobile Intelå¨ GM45 Express Chipset GEM 20100330 DEVELOPMENT x86/MM... unsupported 0 Mesa +Tungsten Graphics, Inc. Mesa DRI R200 (RV280 5964) 20090101 x86/MMX+/3DNow!+/SSE2 TCL DRI2 unsupported 0 Mesa +VIA unsupported 0 VIA +VMware, Inc. Gallium 0.3 on SVGA3D; build: RELEASE; UNRECOGNIZED +VMware, Inc. Gallium 0.4 on i915 (chipset: 945GM) UNRECOGNIZED +VMware, Inc. Gallium 0.4 on llvmpipe UNRECOGNIZED +VMware, Inc. Gallium 0.4 on softpipe UNRECOGNIZED +X.Org Gallium 0.4 on AMD BARTS supported 3 AMD BARTS (HD 6800) +X.Org Gallium 0.4 on AMD CEDAR supported 2 AMD CEDAR (HD 5450) +X.Org Gallium 0.4 on AMD HEMLOCK supported 3 AMD HEMLOCK (HD 5970) +X.Org Gallium 0.4 on AMD JUNIPER supported 3 AMD JUNIPER (HD 5700) +X.Org Gallium 0.4 on AMD REDWOOD supported 3 AMD REDWOOD (HD 5500/5600) +X.Org Gallium 0.4 on AMD RS780 supported 0 AMD RS780 (HD 3200) +X.Org Gallium 0.4 on AMD RS880 supported 1 AMD RS880 (HD 4200) +X.Org Gallium 0.4 on AMD RV610 supported 1 AMD RV610 (HD 2400) +X.Org Gallium 0.4 on AMD RV620 supported 1 AMD RV620 (HD 3400) +X.Org Gallium 0.4 on AMD RV630 supported 2 AMD RV630 (HD 2600) +X.Org Gallium 0.4 on AMD RV635 supported 3 AMD RV635 (HD 3600) +X.Org Gallium 0.4 on AMD RV710 supported 1 AMD RV710 (HD 4300) +X.Org Gallium 0.4 on AMD RV730 supported 3 AMD RV730 (HD 4600) +X.Org Gallium 0.4 on AMD RV740 supported 3 AMD RV740 (HD 4700) +X.Org Gallium 0.4 on AMD RV770 supported 3 AMD RV770 (HD 4800) +X.Org R300 Project Gallium 0.4 on ATI R300 supported 1 ATI R300 (9700) +X.Org R300 Project Gallium 0.4 on ATI R580 supported 3 ATI R580 (X1900) +X.Org R300 Project Gallium 0.4 on ATI RC410 unsupported 0 ATI RC410 (Xpress 200) +X.Org R300 Project Gallium 0.4 on ATI RS482 unsupported 0 ATI RS48x (Xpress 200x) +X.Org R300 Project Gallium 0.4 on ATI RS600 unsupported 0 ATI RS600 (Xpress 3200) +X.Org R300 Project Gallium 0.4 on ATI RS690 supported 1 ATI R300 (9700) +X.Org R300 Project Gallium 0.4 on ATI RV350 supported 0 ATI RV350 (9600) +X.Org R300 Project Gallium 0.4 on ATI RV370 supported 0 ATI RV370 (X300) +X.Org R300 Project Gallium 0.4 on ATI RV410 supported 1 ATI RV410 (X700) +X.Org R300 Project Gallium 0.4 on ATI RV515 supported 1 ATI RV515 +X.Org R300 Project Gallium 0.4 on ATI RV530 supported 1 ATI RV530 +X.Org R300 Project Gallium 0.4 on ATI RV570 supported 3 ATI RV570 (X1900 GT/PRO) +X.Org R300 Project Gallium 0.4 on R420 supported 1 ATI R300 (9700) +X.Org R300 Project Gallium 0.4 on R580 supported 3 ATI R580 (X1900) +X.Org R300 Project Gallium 0.4 on RC410 unsupported 0 ATI RC410 (Xpress 200) +X.Org R300 Project Gallium 0.4 on RS480 unsupported 0 ATI RS48x (Xpress 200x) +X.Org R300 Project Gallium 0.4 on RS482 unsupported 0 ATI RS48x (Xpress 200x) +X.Org R300 Project Gallium 0.4 on RS600 unsupported 0 ATI RS600 (Xpress 3200) +X.Org R300 Project Gallium 0.4 on RS690 supported 1 ATI R300 (9700) +X.Org R300 Project Gallium 0.4 on RS740 supported 1 ATI R300 (9700) +X.Org R300 Project Gallium 0.4 on RV350 supported 0 ATI RV350 (9600) +X.Org R300 Project Gallium 0.4 on RV370 supported 0 ATI RV370 (X300) +X.Org R300 Project Gallium 0.4 on RV410 supported 1 ATI RV410 (X700) +X.Org R300 Project Gallium 0.4 on RV515 supported 1 ATI RV515 +X.Org R300 Project Gallium 0.4 on RV530 supported 1 ATI RV530 +XGI unsupported 0 XGI +nouveau Gallium 0.4 on NV34 UNRECOGNIZED +nouveau Gallium 0.4 on NV36 UNRECOGNIZED +nouveau Gallium 0.4 on NV46 UNRECOGNIZED +nouveau Gallium 0.4 on NV49 UNRECOGNIZED +nouveau Gallium 0.4 on NV4A UNRECOGNIZED +nouveau Gallium 0.4 on NV4B UNRECOGNIZED +nouveau Gallium 0.4 on NV4E UNRECOGNIZED +nouveau Gallium 0.4 on NV50 UNRECOGNIZED +nouveau Gallium 0.4 on NV84 UNRECOGNIZED +nouveau Gallium 0.4 on NV86 UNRECOGNIZED +nouveau Gallium 0.4 on NV92 UNRECOGNIZED +nouveau Gallium 0.4 on NV94 UNRECOGNIZED +nouveau Gallium 0.4 on NV96 UNRECOGNIZED +nouveau Gallium 0.4 on NV98 UNRECOGNIZED +nouveau Gallium 0.4 on NVA0 UNRECOGNIZED +nouveau Gallium 0.4 on NVA3 UNRECOGNIZED +nouveau Gallium 0.4 on NVA5 UNRECOGNIZED +nouveau Gallium 0.4 on NVA8 UNRECOGNIZED +nouveau Gallium 0.4 on NVAA UNRECOGNIZED +nouveau Gallium 0.4 on NVAC UNRECOGNIZED diff --git a/indra/newview/tests/gpus_seen.txt b/indra/newview/tests/gpus_seen.txt new file mode 100644 index 0000000000..c807f22b58 --- /dev/null +++ b/indra/newview/tests/gpus_seen.txt @@ -0,0 +1,1593 @@ +ATI +ATI 3D-Analyze +ATI ASUS A9xxx +ATI ASUS AH24xx +ATI ASUS AH26xx +ATI ASUS AH34xx +ATI ASUS AH36xx +ATI ASUS AH46xx +ATI ASUS AX3xx +ATI ASUS AX5xx +ATI ASUS AX8xx +ATI ASUS EAH38xx +ATI ASUS EAH43xx +ATI ASUS EAH45xx +ATI ASUS EAH48xx +ATI ASUS EAH57xx +ATI ASUS EAH58xx +ATI ASUS X1xxx +ATI All-in-Wonder 9xxx +ATI All-in-Wonder HD +ATI All-in-Wonder PCI-E +ATI All-in-Wonder X1800 +ATI All-in-Wonder X1900 +ATI All-in-Wonder X600 +ATI All-in-Wonder X800 +ATI Diamond X1xxx +ATI Display Adapter +ATI FireGL +ATI FireGL 5200 +ATI FireGL 5xxx +ATI FireMV +ATI Generic +ATI Hercules 9800 +ATI IGP 340M +ATI M52 +ATI M54 +ATI M56 +ATI M71 +ATI M72 +ATI M76 +ATI Mobility Radeon +ATI Mobility Radeon 7xxx +ATI Mobility Radeon 9600 +ATI Mobility Radeon 9700 +ATI Mobility Radeon 9800 +ATI Mobility Radeon HD 2300 +ATI Mobility Radeon HD 2400 +ATI Mobility Radeon HD 2600 +ATI Mobility Radeon HD 2700 +ATI Mobility Radeon HD 3400 +ATI Mobility Radeon HD 3600 +ATI Mobility Radeon HD 3800 +ATI Mobility Radeon HD 4200 +ATI Mobility Radeon HD 4300 +ATI Mobility Radeon HD 4500 +ATI Mobility Radeon HD 4600 +ATI Mobility Radeon HD 4800 +ATI Mobility Radeon HD 5400 +ATI Mobility Radeon HD 5600 +ATI Mobility Radeon X1xxx +ATI Mobility Radeon X2xxx +ATI Mobility Radeon X3xx +ATI Mobility Radeon X6xx +ATI Mobility Radeon X7xx +ATI Mobility Radeon Xxxx +ATI RV380 +ATI RV530 +ATI Radeon 2100 +ATI Radeon 3000 +ATI Radeon 3100 +ATI Radeon 7000 +ATI Radeon 7xxx +ATI Radeon 8xxx +ATI Radeon 9000 +ATI Radeon 9100 +ATI Radeon 9200 +ATI Radeon 9500 +ATI Radeon 9600 +ATI Radeon 9700 +ATI Radeon 9800 +ATI Radeon HD 2300 +ATI Radeon HD 2400 +ATI Radeon HD 2600 +ATI Radeon HD 2900 +ATI Radeon HD 3000 +ATI Radeon HD 3100 +ATI Radeon HD 3200 +ATI Radeon HD 3300 +ATI Radeon HD 3400 +ATI Radeon HD 3600 +ATI Radeon HD 3800 +ATI Radeon HD 4200 +ATI Radeon HD 4300 +ATI Radeon HD 4500 +ATI Radeon HD 4600 +ATI Radeon HD 4700 +ATI Radeon HD 4800 +ATI Radeon HD 5400 +ATI Radeon HD 5500 +ATI Radeon HD 5600 +ATI Radeon HD 5700 +ATI Radeon HD 5800 +ATI Radeon HD 5900 +ATI Radeon HD 6200 +ATI Radeon HD 6300 +ATI Radeon HD 6500 +ATI Radeon HD 6800 +ATI Radeon HD 6900 +ATI Radeon OpenGL +ATI Radeon RV250 +ATI Radeon RV600 +ATI Radeon RX9550 +ATI Radeon VE +ATI Radeon X1000 +ATI Radeon X1200 +ATI Radeon X1300 +ATI Radeon X13xx +ATI Radeon X1400 +ATI Radeon X1500 +ATI Radeon X1600 +ATI Radeon X16xx +ATI Radeon X1700 +ATI Radeon X1800 +ATI Radeon X1900 +ATI Radeon X19xx +ATI Radeon X1xxx +ATI Radeon X300 +ATI Radeon X500 +ATI Radeon X600 +ATI Radeon X700 +ATI Radeon X7xx +ATI Radeon X800 +ATI Radeon Xpress +ATI Rage 128 +ATI Technologies Inc. +ATI Technologies Inc. x86 +ATI Technologies Inc. x86/SSE2 +ATI Technologies Inc. (Vista) ATI Mobility Radeon HD 5730 +ATI Technologies Inc. 256MB ATI Radeon X1300PRO x86/SSE2 +ATI Technologies Inc. AMD 760G +ATI Technologies Inc. AMD 760G (Microsoft WDDM 1.1) +ATI Technologies Inc. AMD 780L +ATI Technologies Inc. AMD FirePro 2270 +ATI Technologies Inc. AMD M860G with ATI Mobility Radeon 4100 +ATI Technologies Inc. AMD M880G with ATI Mobility Radeon HD 4200 +ATI Technologies Inc. AMD M880G with ATI Mobility Radeon HD 4250 +ATI Technologies Inc. AMD RADEON HD 6450 +ATI Technologies Inc. AMD Radeon HD 6200 series Graphics +ATI Technologies Inc. AMD Radeon HD 6250 Graphics +ATI Technologies Inc. AMD Radeon HD 6300 series Graphics +ATI Technologies Inc. AMD Radeon HD 6300M Series +ATI Technologies Inc. AMD Radeon HD 6310 Graphics +ATI Technologies Inc. AMD Radeon HD 6310M +ATI Technologies Inc. AMD Radeon HD 6330M +ATI Technologies Inc. AMD Radeon HD 6350 +ATI Technologies Inc. AMD Radeon HD 6370M +ATI Technologies Inc. AMD Radeon HD 6400M Series +ATI Technologies Inc. AMD Radeon HD 6450 +ATI Technologies Inc. AMD Radeon HD 6470M +ATI Technologies Inc. AMD Radeon HD 6490M +ATI Technologies Inc. AMD Radeon HD 6500M/5600/5700 Series +ATI Technologies Inc. AMD Radeon HD 6530M +ATI Technologies Inc. AMD Radeon HD 6550M +ATI Technologies Inc. AMD Radeon HD 6570 +ATI Technologies Inc. AMD Radeon HD 6570M +ATI Technologies Inc. AMD Radeon HD 6570M/5700 Series +ATI Technologies Inc. AMD Radeon HD 6600M Series +ATI Technologies Inc. AMD Radeon HD 6650M +ATI Technologies Inc. AMD Radeon HD 6670 +ATI Technologies Inc. AMD Radeon HD 6700 Series +ATI Technologies Inc. AMD Radeon HD 6750 +ATI Technologies Inc. AMD Radeon HD 6750M +ATI Technologies Inc. AMD Radeon HD 6770 +ATI Technologies Inc. AMD Radeon HD 6800 Series +ATI Technologies Inc. AMD Radeon HD 6850M +ATI Technologies Inc. AMD Radeon HD 6870 +ATI Technologies Inc. AMD Radeon HD 6870M +ATI Technologies Inc. AMD Radeon HD 6900 Series +ATI Technologies Inc. AMD Radeon HD 6970M +ATI Technologies Inc. AMD Radeon HD 6990 +ATI Technologies Inc. AMD Radeon(TM) HD 6470M +ATI Technologies Inc. ASUS 5870 Eyefinity 6 +ATI Technologies Inc. ASUS AH2600 Series +ATI Technologies Inc. ASUS AH3450 Series +ATI Technologies Inc. ASUS AH3650 Series +ATI Technologies Inc. ASUS AH4650 Series +ATI Technologies Inc. ASUS ARES +ATI Technologies Inc. ASUS EAH2900 Series +ATI Technologies Inc. ASUS EAH3450 Series +ATI Technologies Inc. ASUS EAH3650 Series +ATI Technologies Inc. ASUS EAH4350 series +ATI Technologies Inc. ASUS EAH4550 series +ATI Technologies Inc. ASUS EAH4650 series +ATI Technologies Inc. ASUS EAH4670 series +ATI Technologies Inc. ASUS EAH4750 Series +ATI Technologies Inc. ASUS EAH4770 Series +ATI Technologies Inc. ASUS EAH4770 series +ATI Technologies Inc. ASUS EAH4850 series +ATI Technologies Inc. ASUS EAH5450 Series +ATI Technologies Inc. ASUS EAH5550 Series +ATI Technologies Inc. ASUS EAH5570 series +ATI Technologies Inc. ASUS EAH5670 Series +ATI Technologies Inc. ASUS EAH5750 Series +ATI Technologies Inc. ASUS EAH5770 Series +ATI Technologies Inc. ASUS EAH5830 Series +ATI Technologies Inc. ASUS EAH5850 Series +ATI Technologies Inc. ASUS EAH5870 Series +ATI Technologies Inc. ASUS EAH5970 Series +ATI Technologies Inc. ASUS EAH6850 Series +ATI Technologies Inc. ASUS EAH6870 Series +ATI Technologies Inc. ASUS EAH6950 Series +ATI Technologies Inc. ASUS EAH6970 Series +ATI Technologies Inc. ASUS EAHG4670 series +ATI Technologies Inc. ASUS Extreme AX600 Series +ATI Technologies Inc. ASUS Extreme AX600XT-TD +ATI Technologies Inc. ASUS X1300 Series x86/SSE2 +ATI Technologies Inc. ASUS X1550 Series +ATI Technologies Inc. ASUS X1950 Series x86/SSE2 +ATI Technologies Inc. ASUS X800 Series +ATI Technologies Inc. ASUS X850 Series +ATI Technologies Inc. ATI All-in-Wonder HD +ATI Technologies Inc. ATI FirePro 2260 +ATI Technologies Inc. ATI FirePro 2450 +ATI Technologies Inc. ATI FirePro M5800 +ATI Technologies Inc. ATI FirePro M7740 +ATI Technologies Inc. ATI FirePro M7820 +ATI Technologies Inc. ATI FirePro V3700 (FireGL) +ATI Technologies Inc. ATI FirePro V3800 +ATI Technologies Inc. ATI FirePro V4800 +ATI Technologies Inc. ATI FirePro V4800 (FireGL) +ATI Technologies Inc. ATI FirePro V5800 +ATI Technologies Inc. ATI FirePro V7800 +ATI Technologies Inc. ATI MOBILITY RADEON 9XXX x86/SSE2 +ATI Technologies Inc. ATI MOBILITY RADEON HD 3450 +ATI Technologies Inc. ATI MOBILITY RADEON X1600 +ATI Technologies Inc. ATI MOBILITY RADEON X2300 +ATI Technologies Inc. ATI MOBILITY RADEON X2300 HD x86/SSE2 +ATI Technologies Inc. ATI MOBILITY RADEON X2300 x86/MMX/3DNow!/SSE2 +ATI Technologies Inc. ATI MOBILITY RADEON X2300 x86/SSE2 +ATI Technologies Inc. ATI MOBILITY RADEON X300 +ATI Technologies Inc. ATI MOBILITY RADEON X600 +ATI Technologies Inc. ATI MOBILITY RADEON XPRESS 200 +ATI Technologies Inc. ATI Mobility FireGL V5700 +ATI Technologies Inc. ATI Mobility Radeon 4100 +ATI Technologies Inc. ATI Mobility Radeon Graphics +ATI Technologies Inc. ATI Mobility Radeon HD 2300 +ATI Technologies Inc. ATI Mobility Radeon HD 2400 +ATI Technologies Inc. ATI Mobility Radeon HD 2400 XT +ATI Technologies Inc. ATI Mobility Radeon HD 2600 +ATI Technologies Inc. ATI Mobility Radeon HD 2600 XT +ATI Technologies Inc. ATI Mobility Radeon HD 2700 +ATI Technologies Inc. ATI Mobility Radeon HD 3400 Series +ATI Technologies Inc. ATI Mobility Radeon HD 3430 +ATI Technologies Inc. ATI Mobility Radeon HD 3450 +ATI Technologies Inc. ATI Mobility Radeon HD 3470 +ATI Technologies Inc. ATI Mobility Radeon HD 3470 Hybrid X2 +ATI Technologies Inc. ATI Mobility Radeon HD 3650 +ATI Technologies Inc. ATI Mobility Radeon HD 4200 +ATI Technologies Inc. ATI Mobility Radeon HD 4200 Series +ATI Technologies Inc. ATI Mobility Radeon HD 4225 +ATI Technologies Inc. ATI Mobility Radeon HD 4225 Series +ATI Technologies Inc. ATI Mobility Radeon HD 4250 +ATI Technologies Inc. ATI Mobility Radeon HD 4250 Graphics +ATI Technologies Inc. ATI Mobility Radeon HD 4270 +ATI Technologies Inc. ATI Mobility Radeon HD 4300 Series +ATI Technologies Inc. ATI Mobility Radeon HD 4300/4500 Series +ATI Technologies Inc. ATI Mobility Radeon HD 4330 +ATI Technologies Inc. ATI Mobility Radeon HD 4330 Series +ATI Technologies Inc. ATI Mobility Radeon HD 4350 +ATI Technologies Inc. ATI Mobility Radeon HD 4350 Series +ATI Technologies Inc. ATI Mobility Radeon HD 4500 Series +ATI Technologies Inc. ATI Mobility Radeon HD 4500/5100 Series +ATI Technologies Inc. ATI Mobility Radeon HD 4530 +ATI Technologies Inc. ATI Mobility Radeon HD 4530 Series +ATI Technologies Inc. ATI Mobility Radeon HD 4550 +ATI Technologies Inc. ATI Mobility Radeon HD 4570 +ATI Technologies Inc. ATI Mobility Radeon HD 4600 Series +ATI Technologies Inc. ATI Mobility Radeon HD 4650 +ATI Technologies Inc. ATI Mobility Radeon HD 4650 Series +ATI Technologies Inc. ATI Mobility Radeon HD 4670 +ATI Technologies Inc. ATI Mobility Radeon HD 4830 Series +ATI Technologies Inc. ATI Mobility Radeon HD 4850 +ATI Technologies Inc. ATI Mobility Radeon HD 4870 +ATI Technologies Inc. ATI Mobility Radeon HD 5000 +ATI Technologies Inc. ATI Mobility Radeon HD 5000 Series +ATI Technologies Inc. ATI Mobility Radeon HD 5145 +ATI Technologies Inc. ATI Mobility Radeon HD 5165 +ATI Technologies Inc. ATI Mobility Radeon HD 530v +ATI Technologies Inc. ATI Mobility Radeon HD 5400 Series +ATI Technologies Inc. ATI Mobility Radeon HD 540v +ATI Technologies Inc. ATI Mobility Radeon HD 5430 +ATI Technologies Inc. ATI Mobility Radeon HD 5450 +ATI Technologies Inc. ATI Mobility Radeon HD 5450 Series +ATI Technologies Inc. ATI Mobility Radeon HD 545v +ATI Technologies Inc. ATI Mobility Radeon HD 5470 +ATI Technologies Inc. ATI Mobility Radeon HD 550v +ATI Technologies Inc. ATI Mobility Radeon HD 5600/5700 Series +ATI Technologies Inc. ATI Mobility Radeon HD 560v +ATI Technologies Inc. ATI Mobility Radeon HD 5650 +ATI Technologies Inc. ATI Mobility Radeon HD 5700 Series +ATI Technologies Inc. ATI Mobility Radeon HD 5730 +ATI Technologies Inc. ATI Mobility Radeon HD 5800 Series +ATI Technologies Inc. ATI Mobility Radeon HD 5850 +ATI Technologies Inc. ATI Mobility Radeon HD 5870 +ATI Technologies Inc. ATI Mobility Radeon HD 6300 series +ATI Technologies Inc. ATI Mobility Radeon HD 6370 +ATI Technologies Inc. ATI Mobility Radeon HD 6470M +ATI Technologies Inc. ATI Mobility Radeon HD 6550 +ATI Technologies Inc. ATI Mobility Radeon HD 6570 +ATI Technologies Inc. ATI Mobility Radeon X1300 +ATI Technologies Inc. ATI Mobility Radeon X1300 x86/MMX/3DNow!/SSE2 +ATI Technologies Inc. ATI Mobility Radeon X1300 x86/SSE2 +ATI Technologies Inc. ATI Mobility Radeon X1350 +ATI Technologies Inc. ATI Mobility Radeon X1350 x86/SSE2 +ATI Technologies Inc. ATI Mobility Radeon X1400 +ATI Technologies Inc. ATI Mobility Radeon X1400 x86/SSE2 +ATI Technologies Inc. ATI Mobility Radeon X1600 +ATI Technologies Inc. ATI Mobility Radeon X1600 x86/SSE2 +ATI Technologies Inc. ATI Mobility Radeon X1700 x86/SSE2 +ATI Technologies Inc. ATI Mobility Radeon X2300 +ATI Technologies Inc. ATI Mobility Radeon X2300 (Omega 3.8.442) +ATI Technologies Inc. ATI Mobility Radeon X2300 x86 +ATI Technologies Inc. ATI Mobility Radeon X2300 x86/MMX/3DNow!/SSE2 +ATI Technologies Inc. ATI Mobility Radeon X2300 x86/SSE2 +ATI Technologies Inc. ATI Mobility Radeon X2500 +ATI Technologies Inc. ATI Mobility Radeon X2500 x86/SSE2 +ATI Technologies Inc. ATI Mobility Radeon. HD 530v +ATI Technologies Inc. ATI Mobility Radeon. HD 5470 +ATI Technologies Inc. ATI RADEON HD 3200 T25XX by CAMILO +ATI Technologies Inc. ATI RADEON XPRESS 1100 +ATI Technologies Inc. ATI RADEON XPRESS 200 Series +ATI Technologies Inc. ATI RADEON XPRESS 200 Series x86/SSE2 +ATI Technologies Inc. ATI RADEON XPRESS 200M SERIES +ATI Technologies Inc. ATI Radeon +ATI Technologies Inc. ATI Radeon 2100 +ATI Technologies Inc. ATI Radeon 2100 (Microsoft - WDDM) +ATI Technologies Inc. ATI Radeon 2100 Graphics +ATI Technologies Inc. ATI Radeon 3000 +ATI Technologies Inc. ATI Radeon 3000 Graphics +ATI Technologies Inc. ATI Radeon 3100 Graphics +ATI Technologies Inc. ATI Radeon 5xxx series +ATI Technologies Inc. ATI Radeon 9550 / X1050 Series +ATI Technologies Inc. ATI Radeon 9550 / X1050 Series x86/MMX/3DNow!/SSE +ATI Technologies Inc. ATI Radeon 9550 / X1050 Series x86/SSE2 +ATI Technologies Inc. ATI Radeon 9550 / X1050 Series(Microsoft - WDDM) +ATI Technologies Inc. ATI Radeon 9600 / X1050 Series +ATI Technologies Inc. ATI Radeon 9600/9550/X1050 Series +ATI Technologies Inc. ATI Radeon BA Prototype OpenGL Engine +ATI Technologies Inc. ATI Radeon BB Prototype OpenGL Engine +ATI Technologies Inc. ATI Radeon Cedar PRO Prototype OpenGL Engine +ATI Technologies Inc. ATI Radeon Cypress PRO Prototype OpenGL Engine +ATI Technologies Inc. ATI Radeon Graphics Processor +ATI Technologies Inc. ATI Radeon HD 2200 Graphics +ATI Technologies Inc. ATI Radeon HD 2350 +ATI Technologies Inc. ATI Radeon HD 2400 +ATI Technologies Inc. ATI Radeon HD 2400 OpenGL Engine +ATI Technologies Inc. ATI Radeon HD 2400 PRO +ATI Technologies Inc. ATI Radeon HD 2400 PRO AGP +ATI Technologies Inc. ATI Radeon HD 2400 Pro +ATI Technologies Inc. ATI Radeon HD 2400 Series +ATI Technologies Inc. ATI Radeon HD 2400 XT +ATI Technologies Inc. ATI Radeon HD 2400 XT OpenGL Engine +ATI Technologies Inc. ATI Radeon HD 2600 OpenGL Engine +ATI Technologies Inc. ATI Radeon HD 2600 PRO +ATI Technologies Inc. ATI Radeon HD 2600 PRO OpenGL Engine +ATI Technologies Inc. ATI Radeon HD 2600 Pro +ATI Technologies Inc. ATI Radeon HD 2600 Series +ATI Technologies Inc. ATI Radeon HD 2600 XT +ATI Technologies Inc. ATI Radeon HD 2900 GT +ATI Technologies Inc. ATI Radeon HD 2900 XT +ATI Technologies Inc. ATI Radeon HD 3200 Graphics +ATI Technologies Inc. ATI Radeon HD 3300 Graphics +ATI Technologies Inc. ATI Radeon HD 3400 Series +ATI Technologies Inc. ATI Radeon HD 3450 +ATI Technologies Inc. ATI Radeon HD 3450 - Dell Optiplex +ATI Technologies Inc. ATI Radeon HD 3470 +ATI Technologies Inc. ATI Radeon HD 3470 - Dell Optiplex +ATI Technologies Inc. ATI Radeon HD 3550 +ATI Technologies Inc. ATI Radeon HD 3600 Series +ATI Technologies Inc. ATI Radeon HD 3650 +ATI Technologies Inc. ATI Radeon HD 3650 AGP +ATI Technologies Inc. ATI Radeon HD 3730 +ATI Technologies Inc. ATI Radeon HD 3800 Series +ATI Technologies Inc. ATI Radeon HD 3850 +ATI Technologies Inc. ATI Radeon HD 3850 AGP +ATI Technologies Inc. ATI Radeon HD 3870 +ATI Technologies Inc. ATI Radeon HD 3870 X2 +ATI Technologies Inc. ATI Radeon HD 4200 +ATI Technologies Inc. ATI Radeon HD 4250 +ATI Technologies Inc. ATI Radeon HD 4250 Graphics +ATI Technologies Inc. ATI Radeon HD 4270 +ATI Technologies Inc. ATI Radeon HD 4290 +ATI Technologies Inc. ATI Radeon HD 4300 Series +ATI Technologies Inc. ATI Radeon HD 4300/4500 Series +ATI Technologies Inc. ATI Radeon HD 4350 +ATI Technologies Inc. ATI Radeon HD 4350 (Microsoft WDDM 1.1) +ATI Technologies Inc. ATI Radeon HD 4450 +ATI Technologies Inc. ATI Radeon HD 4500 Series +ATI Technologies Inc. ATI Radeon HD 4550 +ATI Technologies Inc. ATI Radeon HD 4600 Series +ATI Technologies Inc. ATI Radeon HD 4650 +ATI Technologies Inc. ATI Radeon HD 4670 +ATI Technologies Inc. ATI Radeon HD 4670 OpenGL Engine +ATI Technologies Inc. ATI Radeon HD 4700 Series +ATI Technologies Inc. ATI Radeon HD 4720 +ATI Technologies Inc. ATI Radeon HD 4730 +ATI Technologies Inc. ATI Radeon HD 4730 Series +ATI Technologies Inc. ATI Radeon HD 4750 +ATI Technologies Inc. ATI Radeon HD 4770 +ATI Technologies Inc. ATI Radeon HD 4800 Series +ATI Technologies Inc. ATI Radeon HD 4850 +ATI Technologies Inc. ATI Radeon HD 4850 OpenGL Engine +ATI Technologies Inc. ATI Radeon HD 4850 Series +ATI Technologies Inc. ATI Radeon HD 4870 +ATI Technologies Inc. ATI Radeon HD 4870 OpenGL Engine +ATI Technologies Inc. ATI Radeon HD 4870 X2 +ATI Technologies Inc. ATI Radeon HD 5400 Series +ATI Technologies Inc. ATI Radeon HD 5450 +ATI Technologies Inc. ATI Radeon HD 5500 Series +ATI Technologies Inc. ATI Radeon HD 5570 +ATI Technologies Inc. ATI Radeon HD 5600 Series +ATI Technologies Inc. ATI Radeon HD 5630 +ATI Technologies Inc. ATI Radeon HD 5670 +ATI Technologies Inc. ATI Radeon HD 5670 OpenGL Engine +ATI Technologies Inc. ATI Radeon HD 5700 Series +ATI Technologies Inc. ATI Radeon HD 5750 +ATI Technologies Inc. ATI Radeon HD 5750 OpenGL Engine +ATI Technologies Inc. ATI Radeon HD 5770 +ATI Technologies Inc. ATI Radeon HD 5770 OpenGL Engine +ATI Technologies Inc. ATI Radeon HD 5800 Series +ATI Technologies Inc. ATI Radeon HD 5850 +ATI Technologies Inc. ATI Radeon HD 5870 +ATI Technologies Inc. ATI Radeon HD 5870 OpenGL Engine +ATI Technologies Inc. ATI Radeon HD 5900 Series +ATI Technologies Inc. ATI Radeon HD 5970 +ATI Technologies Inc. ATI Radeon HD 6230 +ATI Technologies Inc. ATI Radeon HD 6250 +ATI Technologies Inc. ATI Radeon HD 6350 +ATI Technologies Inc. ATI Radeon HD 6390 +ATI Technologies Inc. ATI Radeon HD 6490M OpenGL Engine +ATI Technologies Inc. ATI Radeon HD 6510 +ATI Technologies Inc. ATI Radeon HD 6570M +ATI Technologies Inc. ATI Radeon HD 6750 +ATI Technologies Inc. ATI Radeon HD 6750M OpenGL Engine +ATI Technologies Inc. ATI Radeon HD 6770 +ATI Technologies Inc. ATI Radeon HD 6770M OpenGL Engine +ATI Technologies Inc. ATI Radeon HD 6800 Series +ATI Technologies Inc. ATI Radeon HD 6970M OpenGL Engine +ATI Technologies Inc. ATI Radeon HD3750 +ATI Technologies Inc. ATI Radeon HD4300/HD4500 series +ATI Technologies Inc. ATI Radeon HD4670 +ATI Technologies Inc. ATI Radeon Juniper LE Prototype OpenGL Engine +ATI Technologies Inc. ATI Radeon RV710 Prototype OpenGL Engine +ATI Technologies Inc. ATI Radeon RV730 Prototype OpenGL Engine +ATI Technologies Inc. ATI Radeon RV770 Prototype OpenGL Engine +ATI Technologies Inc. ATI Radeon RV790 Prototype OpenGL Engine +ATI Technologies Inc. ATI Radeon Redwood PRO Prototype OpenGL Engine +ATI Technologies Inc. ATI Radeon Redwood XT Prototype OpenGL Engine +ATI Technologies Inc. ATI Radeon Whistler PRO/LP Prototype OpenGL Engine +ATI Technologies Inc. ATI Radeon X1050 +ATI Technologies Inc. ATI Radeon X1050 Series +ATI Technologies Inc. ATI Radeon X1200 +ATI Technologies Inc. ATI Radeon X1200 Series +ATI Technologies Inc. ATI Radeon X1200 Series x86/MMX/3DNow!/SSE2 +ATI Technologies Inc. ATI Radeon X1250 +ATI Technologies Inc. ATI Radeon X1250 x86/MMX/3DNow!/SSE2 +ATI Technologies Inc. ATI Radeon X1270 +ATI Technologies Inc. ATI Radeon X1270 x86/MMX/3DNow!/SSE2 +ATI Technologies Inc. ATI Radeon X1300/X1550 Series +ATI Technologies Inc. ATI Radeon X1550 Series +ATI Technologies Inc. ATI Radeon X1600 OpenGL Engine +ATI Technologies Inc. ATI Radeon X1900 OpenGL Engine +ATI Technologies Inc. ATI Radeon X1950 GT +ATI Technologies Inc. ATI Radeon X300/X550/X1050 Series +ATI Technologies Inc. ATI Radeon Xpress 1100 +ATI Technologies Inc. ATI Radeon Xpress 1150 +ATI Technologies Inc. ATI Radeon Xpress 1150 x86/MMX/3DNow!/SSE2 +ATI Technologies Inc. ATI Radeon Xpress 1200 +ATI Technologies Inc. ATI Radeon Xpress 1200 Series +ATI Technologies Inc. ATI Radeon Xpress 1200 Series x86/MMX/3DNow!/SSE2 +ATI Technologies Inc. ATI Radeon Xpress 1200 x86/MMX/3DNow!/SSE2 +ATI Technologies Inc. ATI Radeon Xpress 1250 +ATI Technologies Inc. ATI Radeon Xpress 1250 x86/SSE2 +ATI Technologies Inc. ATI Radeon Xpress Series +ATI Technologies Inc. ATI Yamaha HD 9000 +ATI Technologies Inc. ATi RS880M +ATI Technologies Inc. Carte graphique VGA standard +ATI Technologies Inc. Diamond Radeon X1550 Series +ATI Technologies Inc. EG JUNIPER +ATI Technologies Inc. EG PARK +ATI Technologies Inc. FireGL V3100 Pentium 4 (SSE2) +ATI Technologies Inc. FireMV 2400 PCI DDR x86 +ATI Technologies Inc. FireMV 2400 PCI DDR x86/SSE2 +ATI Technologies Inc. GeCube Radeon X1550 +ATI Technologies Inc. Geforce 9500 GT +ATI Technologies Inc. Geforce 9500GT +ATI Technologies Inc. Geforce 9800 GT +ATI Technologies Inc. HD3730 +ATI Technologies Inc. HIGHTECH EXCALIBUR RADEON 9550SE Series +ATI Technologies Inc. HIGHTECH EXCALIBUR X700 PRO +ATI Technologies Inc. M21 x86/MMX/3DNow!/SSE2 +ATI Technologies Inc. M76M +ATI Technologies Inc. MOBILITY RADEON 7500 DDR x86/SSE2 +ATI Technologies Inc. MOBILITY RADEON 9000 DDR x86/SSE2 +ATI Technologies Inc. MOBILITY RADEON 9000 IGPRADEON 9100 IGP DDR x86/SSE2 +ATI Technologies Inc. MOBILITY RADEON 9600 x86/SSE2 +ATI Technologies Inc. MOBILITY RADEON 9700 x86/SSE2 +ATI Technologies Inc. MOBILITY RADEON X300 x86/SSE2 +ATI Technologies Inc. MOBILITY RADEON X600 x86/SSE2 +ATI Technologies Inc. MOBILITY RADEON X700 SE x86 +ATI Technologies Inc. MOBILITY RADEON X700 x86/SSE2 +ATI Technologies Inc. MSI RX9550SE +ATI Technologies Inc. Mobility Radeon X2300 HD +ATI Technologies Inc. Mobility Radeon X2300 HD x86/SSE2 +ATI Technologies Inc. RADEON 7000 DDR x86/MMX/3DNow!/SSE +ATI Technologies Inc. RADEON 7000 DDR x86/SSE2 +ATI Technologies Inc. RADEON 7500 DDR x86/MMX/3DNow!/SSE2 +ATI Technologies Inc. RADEON 7500 DDR x86/SSE2 +ATI Technologies Inc. RADEON 9100 IGP DDR x86/SSE2 +ATI Technologies Inc. RADEON 9200 DDR x86/MMX/3DNow!/SSE +ATI Technologies Inc. RADEON 9200 DDR x86/SSE2 +ATI Technologies Inc. RADEON 9200 PRO DDR x86/MMX/3DNow!/SSE +ATI Technologies Inc. RADEON 9200 Series DDR x86/MMX/3DNow!/SSE +ATI Technologies Inc. RADEON 9200 Series DDR x86/MMX/3DNow!/SSE2 +ATI Technologies Inc. RADEON 9200 Series DDR x86/SSE +ATI Technologies Inc. RADEON 9200 Series DDR x86/SSE2 +ATI Technologies Inc. RADEON 9200SE DDR x86/MMX/3DNow!/SSE2 +ATI Technologies Inc. RADEON 9200SE DDR x86/SSE2 +ATI Technologies Inc. RADEON 9250/9200 Series DDR x86/MMX/3DNow!/SSE +ATI Technologies Inc. RADEON 9250/9200 Series DDR x86/MMX/3DNow!/SSE2 +ATI Technologies Inc. RADEON 9250/9200 Series DDR x86/SSE2 +ATI Technologies Inc. RADEON 9500 +ATI Technologies Inc. RADEON 9550 x86/SSE2 +ATI Technologies Inc. RADEON 9600 SERIES +ATI Technologies Inc. RADEON 9600 SERIES x86/MMX/3DNow!/SSE2 +ATI Technologies Inc. RADEON 9600 TX x86/SSE2 +ATI Technologies Inc. RADEON 9600 x86/MMX/3DNow!/SSE2 +ATI Technologies Inc. RADEON 9600 x86/SSE2 +ATI Technologies Inc. RADEON 9700 PRO x86/MMX/3DNow!/SSE +ATI Technologies Inc. RADEON 9800 PRO +ATI Technologies Inc. RADEON 9800 x86/SSE2 +ATI Technologies Inc. RADEON IGP 340M DDR x86/SSE2 +ATI Technologies Inc. RADEON X300 Series x86/SSE2 +ATI Technologies Inc. RADEON X300 x86/SSE2 +ATI Technologies Inc. RADEON X300/X550 Series x86/SSE2 +ATI Technologies Inc. RADEON X550 x86/MMX/3DNow!/SSE2 +ATI Technologies Inc. RADEON X550 x86/SSE2 +ATI Technologies Inc. RADEON X600 Series +ATI Technologies Inc. RADEON X600 x86/SSE2 +ATI Technologies Inc. RADEON X700 PRO x86/SSE2 +ATI Technologies Inc. RADEON X800 SE x86/MMX/3DNow!/SSE2 +ATI Technologies Inc. RADEON X800GT +ATI Technologies Inc. RADEON XPRESS 200 Series SW TCL x86/MMX/3DNow!/SSE2 +ATI Technologies Inc. RADEON XPRESS 200 Series SW TCL x86/SSE2 +ATI Technologies Inc. RADEON XPRESS 200 Series x86/SSE2 +ATI Technologies Inc. RADEON XPRESS 200M Series SW TCL x86/MMX/3DNow!/SSE2 +ATI Technologies Inc. RADEON XPRESS 200M Series SW TCL x86/SSE2 +ATI Technologies Inc. RADEON XPRESS 200M Series x86/MMX/3DNow!/SSE2 +ATI Technologies Inc. RADEON XPRESS 200M Series x86/SSE2 +ATI Technologies Inc. RADEON XPRESS Series x86/MMX/3DNow!/SSE2 +ATI Technologies Inc. RADEON XPRESS Series x86/SSE2 +ATI Technologies Inc. RS740 +ATI Technologies Inc. RS780C +ATI Technologies Inc. RS780M +ATI Technologies Inc. RS880 +ATI Technologies Inc. RV410 Pro x86/SSE2 +ATI Technologies Inc. RV790 +ATI Technologies Inc. Radeon (TM) HD 6470M +ATI Technologies Inc. Radeon (TM) HD 6490M +ATI Technologies Inc. Radeon (TM) HD 6770M +ATI Technologies Inc. Radeon 7000 DDR x86/SSE2 +ATI Technologies Inc. Radeon 7000 SDR x86/SSE2 +ATI Technologies Inc. Radeon 7500 DDR x86/SSE2 +ATI Technologies Inc. Radeon 9000 DDR x86/SSE2 +ATI Technologies Inc. Radeon DDR x86/MMX/3DNow!/SSE2 +ATI Technologies Inc. Radeon DDR x86/SSE +ATI Technologies Inc. Radeon DDR x86/SSE2 +ATI Technologies Inc. Radeon HD 6310 +ATI Technologies Inc. Radeon HD 6800 Series +ATI Technologies Inc. Radeon SDR x86/SSE2 +ATI Technologies Inc. Radeon X1300 Series +ATI Technologies Inc. Radeon X1300 Series x86/MMX/3DNow!/SSE2 +ATI Technologies Inc. Radeon X1300 Series x86/SSE2 +ATI Technologies Inc. Radeon X1300/X1550 Series +ATI Technologies Inc. Radeon X1300/X1550 Series x86/SSE2 +ATI Technologies Inc. Radeon X1550 64-bit (Microsoft - WDDM) +ATI Technologies Inc. Radeon X1550 Series +ATI Technologies Inc. Radeon X1550 Series x86/SSE2 +ATI Technologies Inc. Radeon X1600 +ATI Technologies Inc. Radeon X1600 Pro / X1300XT x86/MMX/3DNow!/SSE2 +ATI Technologies Inc. Radeon X1600 Series x86/SSE2 +ATI Technologies Inc. Radeon X1600/X1650 Series +ATI Technologies Inc. Radeon X1650 Series +ATI Technologies Inc. Radeon X1650 Series x86/MMX/3DNow!/SSE2 +ATI Technologies Inc. Radeon X1650 Series x86/SSE2 +ATI Technologies Inc. Radeon X1900 Series x86/MMX/3DNow!/SSE2 +ATI Technologies Inc. Radeon X1950 Pro +ATI Technologies Inc. Radeon X1950 Pro x86/MMX/3DNow!/SSE2 +ATI Technologies Inc. Radeon X1950 Series +ATI Technologies Inc. Radeon X1950 Series (Microsoft - WDDM) +ATI Technologies Inc. Radeon X300/X550/X1050 Series +ATI Technologies Inc. Radeon X550/X700 Series +ATI Technologies Inc. Radeon X550XTX x86/MMX/3DNow!/SSE2 +ATI Technologies Inc. SAPPHIRE RADEON X300SE +ATI Technologies Inc. SAPPHIRE RADEON X300SE x86/MMX/3DNow!/SSE2 +ATI Technologies Inc. SAPPHIRE RADEON X300SE x86/SSE2 +ATI Technologies Inc. SAPPHIRE Radeon X1550 Series +ATI Technologies Inc. SAPPHIRE Radeon X1550 Series x86/MMX/3DNow!/SSE2 +ATI Technologies Inc. Sapphire Radeon HD 3730 +ATI Technologies Inc. Sapphire Radeon HD 3750 +ATI Technologies Inc. Standard VGA Graphics Adapter +ATI Technologies Inc. Tul, RADEON X600 PRO +ATI Technologies Inc. Tul, RADEON X600 PRO x86/SSE2 +ATI Technologies Inc. Tul, RADEON X700 PRO +ATI Technologies Inc. Tul, RADEON X700 PRO x86/MMX/3DNow!/SSE2 +ATI Technologies Inc. VisionTek Radeon 4350 +ATI Technologies Inc. VisionTek Radeon X1550 Series +ATI Technologies Inc. WRESTLER 9802 +ATI Technologies Inc. WRESTLER 9803 +ATI Technologies Inc. XFX Radeon HD 4570 +ATI Technologies Inc. Yamaha ATI HD 9000da/s +ATI Technologies Inc. Yamaha ATI HD 9000da/s 2048 +Advanced Micro Devices, Inc. Mesa DRI R600 (RS780 9612) 20090101 x86/MMX+/3DNow!+/SSE2 TCL DRI2 +Advanced Micro Devices, Inc. Mesa DRI R600 (RS880 9710) 20090101 x86/MMX+/3DNow!+/SSE2 TCL DRI2 +Advanced Micro Devices, Inc. Mesa DRI R600 (RS880 9712) 20090101 TCL +Advanced Micro Devices, Inc. Mesa DRI R600 (RV610 94C1) 20090101 x86/MMX+/3DNow!+/SSE2 TCL DRI2 +Advanced Micro Devices, Inc. Mesa DRI R600 (RV610 94C9) 20090101 x86/MMX/SSE2 TCL DRI2 +Advanced Micro Devices, Inc. Mesa DRI R600 (RV620 95C4) 20090101 x86/MMX/SSE2 TCL DRI2 +Advanced Micro Devices, Inc. Mesa DRI R600 (RV620 95C5) 20090101 x86/MMX+/3DNow!+/SSE2 TCL DRI2 +Advanced Micro Devices, Inc. Mesa DRI R600 (RV620 95C5) 20090101 x86/MMX/SSE2 TCL DRI2 +Advanced Micro Devices, Inc. Mesa DRI R600 (RV635 9596) 20090101 x86/MMX+/3DNow!+/SSE TCL DRI2 +Advanced Micro Devices, Inc. Mesa DRI R600 (RV670 9505) 20090101 x86/MMX+/3DNow!+/SSE2 TCL DRI2 +Advanced Micro Devices, Inc. Mesa DRI R600 (RV710 9552) 20090101 x86/MMX/SSE2 TCL DRI2 +Advanced Micro Devices, Inc. Mesa DRI R600 (RV730 9490) 20090101 x86/MMX+/3DNow!+/SSE2 TCL DRI2 +Advanced Micro Devices, Inc. Mesa DRI R600 (RV730 9490) 20090101 x86/MMX/SSE2 TCL DRI2 +Advanced Micro Devices, Inc. Mesa DRI R600 (RV730 9498) 20090101 TCL DRI2 +Advanced Micro Devices, Inc. Mesa DRI R600 (RV770 9440) 20090101 x86/MMX+/3DNow!+/SSE2 TCL DRI2 +Advanced Micro Devices, Inc. Mesa DRI R600 (RV770 9442) 20090101 x86/MMX/SSE2 TCL DRI2 +Alex Mohr GL Hijacker! +Apple Software Renderer +DRI R300 Project Mesa DRI R300 (RS400 5954) 20090101 x86/MMX+/3DNow!+/SSE2 NO-TCL DRI2 +DRI R300 Project Mesa DRI R300 (RS400 5975) 20090101 x86/MMX+/3DNow!+/SSE2 NO-TCL DRI2 +DRI R300 Project Mesa DRI R300 (RS400 5A62) 20090101 x86/MMX/SSE2 NO-TCL DRI2 +DRI R300 Project Mesa DRI R300 (RS600 7941) 20090101 x86/MMX/SSE2 NO-TCL +DRI R300 Project Mesa DRI R300 (RS690 791F) 20090101 x86/MMX+/3DNow!+/SSE2 NO-TCL DRI2 +DRI R300 Project Mesa DRI R300 (RV350 4151) 20090101 AGP 4x x86/MMX+/3DNow!+/SSE TCL +DRI R300 Project Mesa DRI R300 (RV350 4153) 20090101 AGP 8x x86/MMX+/3DNow!+/SSE TCL +DRI R300 Project Mesa DRI R300 (RV380 3150) 20090101 x86/MMX+/3DNow!+/SSE2 TCL DRI2 +DRI R300 Project Mesa DRI R300 (RV380 3150) 20090101 x86/MMX/SSE2 TCL DRI2 +DRI R300 Project Mesa DRI R300 (RV380 5B60) 20090101 x86/MMX/SSE2 TCL DRI2 +DRI R300 Project Mesa DRI R300 (RV380 5B62) 20090101 x86/MMX+/3DNow!+/SSE2 TCL DRI2 +DRI R300 Project Mesa DRI R300 (RV515 7145) 20090101 x86/MMX/SSE2 TCL DRI2 +DRI R300 Project Mesa DRI R300 (RV515 7146) 20090101 x86/MMX+/3DNow!+/SSE2 TCL DRI2 +DRI R300 Project Mesa DRI R300 (RV515 7146) 20090101 x86/MMX/SSE2 TCL DRI2 +DRI R300 Project Mesa DRI R300 (RV515 7149) 20090101 x86/MMX/SSE2 TCL DRI2 +DRI R300 Project Mesa DRI R300 (RV515 714A) 20090101 x86/MMX/SSE2 TCL +DRI R300 Project Mesa DRI R300 (RV515 714A) 20090101 x86/MMX/SSE2 TCL DRI2 +DRI R300 Project Mesa DRI R300 (RV530 71C4) 20090101 x86/MMX/SSE2 TCL DRI2 +GPU_CLASS_UNKNOWN +Humper Chromium +Intel +Intel HD Graphics Family +Intel 3D-Analyze v2.2 - http://www.tommti-systems.com +Intel 3D-Analyze v2.3 - http://www.tommti-systems.com +Intel 4 Series Internal Chipset +Intel 830M +Intel 845G +Intel 855GM +Intel 865G +Intel 915G +Intel 915GM +Intel 945G +Intel 945GM +Intel 950 +Intel 965 +Intel B43 Express Chipset +Intel Bear Lake +Intel Broadwater +Intel Brookdale +Intel Cantiga +Intel Eaglelake +Intel Familia Mobile 45 Express Chipset (Microsoft Corporation - WDDM 1.1) +Intel G33 +Intel G41 +Intel G41 Express Chipset +Intel G45 +Intel G45/G43 Express Chipset +Intel Graphics Media Accelerator HD +Intel HD Graphics +Intel HD Graphics 100 +Intel HD Graphics 200 +Intel HD Graphics 200 BR-1101-00SH +Intel HD Graphics 200 BR-1101-00SJ +Intel HD Graphics 200 BR-1101-00SK +Intel HD Graphics 200 BR-1101-01M5 +Intel HD Graphics 200 BR-1101-01M6 +Intel HD Graphics BR-1004-01Y1 +Intel HD Graphics BR-1006-0364 +Intel HD Graphics BR-1006-0365 +Intel HD Graphics BR-1006-0366 +Intel HD Graphics BR-1007-02G4 +Intel HD Graphics BR-1101-04SY +Intel HD Graphics BR-1101-04SZ +Intel HD Graphics BR-1101-04T0 +Intel HD Graphics BR-1101-04T9 +Intel HD Graphics Family +Intel HD Graphics Family BR-1012-00Y8 +Intel HD Graphics Family BR-1012-00YF +Intel HD Graphics Family BR-1012-00ZD +Intel HD Graphics Family BR-1102-00ML +Intel Inc. Intel GMA 900 OpenGL Engine +Intel Inc. Intel GMA 950 OpenGL Engine +Intel Inc. Intel GMA X3100 OpenGL Engine +Intel Inc. Intel HD Graphics 3000 OpenGL Engine +Intel Inc. Intel HD Graphics OpenGL Engine +Intel Inc. Intel HD xxxx OpenGL Engine +Intel Intel 845G +Intel Intel 855GM +Intel Intel 865G +Intel Intel 915G +Intel Intel 915GM +Intel Intel 945G +Intel Intel 945GM +Intel Intel 965/963 Graphics Media Accelerator +Intel Intel Bear Lake B +Intel Intel Broadwater G +Intel Intel Brookdale-G +Intel Intel Calistoga +Intel Intel Cantiga +Intel Intel Eaglelake +Intel Intel Grantsdale-G +Intel Intel HD Graphics 3000 +Intel Intel Lakeport +Intel Intel Montara-GM +Intel Intel Pineview Platform +Intel Intel Springdale-G +Intel Mobile - famiglia Express Chipset 45 (Microsoft Corporation - WDDM 1.1) +Intel Mobile 4 Series +Intel Mobile 4 Series Express Chipset Family +Intel Mobile 45 Express Chipset Family (Microsoft Corporation - WDDM 1.1) +Intel Mobile HD Graphics +Intel Mobile SandyBridge HD Graphics +Intel Montara +Intel Pineview +Intel Q45/Q43 Express Chipset +Intel Royal BNA Driver +Intel SandyBridge HD Graphics +Intel SandyBridge HD Graphics BR-1006-00V8 +Intel Springdale +Intel X3100 +Intergraph wcgdrv 06.05.06.18 +Intergraph wcgdrv 06.06.00.35 +LegendgrafiX Mobile 945 Express C/TitaniumGL/GAC/D3D ACCELERATION/6x86/1 THREADs | http://LegendgrafiX.tk +LegendgrafiX NVIDIA GeForce GT 430/TitaniumGL/GAC/D3D ACCELERATION/6x86/1 THREADs | http://LegendgrafiX.tk +Linden Lab Headless +Matrox +Mesa +Mesa Project Software Rasterizer +NVIDIA /PCI/SSE2 +NVIDIA /PCI/SSE2/3DNOW! +NVIDIA 205 +NVIDIA 210 +NVIDIA 310 +NVIDIA 310M +NVIDIA 315 +NVIDIA 315M +NVIDIA 320M +NVIDIA C51 +NVIDIA D10M2-20/PCI/SSE2 +NVIDIA D10P1-25/PCI/SSE2 +NVIDIA D10P1-30/PCI/SSE2 +NVIDIA D10P2-50/PCI/SSE2 +NVIDIA D11M2-30/PCI/SSE2 +NVIDIA D12-P1-35/PCI/SSE2 +NVIDIA D12U-15/PCI/SSE2 +NVIDIA D13M1-40/PCI/SSE2 +NVIDIA D13P1-40/PCI/SSE2 +NVIDIA D13U-10/PCI/SSE2 +NVIDIA D13U/PCI/SSE2 +NVIDIA D9M +NVIDIA D9M-20/PCI/SSE2 +NVIDIA Entry Graphics/PCI/SSE2 +NVIDIA Entry Graphics/PCI/SSE2/3DNOW! +NVIDIA G 102M +NVIDIA G 103M +NVIDIA G 105M +NVIDIA G 110M +NVIDIA G100 +NVIDIA G102M +NVIDIA G103M +NVIDIA G105M +NVIDIA G210 +NVIDIA G210M +NVIDIA G70/PCI/SSE2 +NVIDIA G72 +NVIDIA G73 +NVIDIA G84 +NVIDIA G86 +NVIDIA G92 +NVIDIA G92-200/PCI/SSE2 +NVIDIA G94 +NVIDIA G96/PCI/SSE2 +NVIDIA G98/PCI/SSE2 +NVIDIA GT 120 +NVIDIA GT 130 +NVIDIA GT 130M +NVIDIA GT 140 +NVIDIA GT 150 +NVIDIA GT 160M +NVIDIA GT 220 +NVIDIA GT 220/PCI/SSE2 +NVIDIA GT 220/PCI/SSE2/3DNOW! +NVIDIA GT 230 +NVIDIA GT 230M +NVIDIA GT 240 +NVIDIA GT 240M +NVIDIA GT 250M +NVIDIA GT 260M +NVIDIA GT 320 +NVIDIA GT 320M +NVIDIA GT 330 +NVIDIA GT 330M +NVIDIA GT 340 +NVIDIA GT 420 +NVIDIA GT 430 +NVIDIA GT 440 +NVIDIA GT 450 +NVIDIA GT 520 +NVIDIA GT 540 +NVIDIA GT 540M +NVIDIA GT-120 +NVIDIA GT200/PCI/SSE2 +NVIDIA GTS 150 +NVIDIA GTS 240 +NVIDIA GTS 250 +NVIDIA GTS 350M +NVIDIA GTS 360 +NVIDIA GTS 360M +NVIDIA GTS 450 +NVIDIA GTX 260 +NVIDIA GTX 260M +NVIDIA GTX 270 +NVIDIA GTX 280 +NVIDIA GTX 285 +NVIDIA GTX 290 +NVIDIA GTX 460 +NVIDIA GTX 460M +NVIDIA GTX 465 +NVIDIA GTX 470 +NVIDIA GTX 470M +NVIDIA GTX 480 +NVIDIA GTX 480M +NVIDIA GTX 550 Ti +NVIDIA GTX 560 +NVIDIA GTX 560 Ti +NVIDIA GTX 570 +NVIDIA GTX 580 +NVIDIA GTX 590 +NVIDIA GeForce +NVIDIA GeForce 2 +NVIDIA GeForce 205/PCI/SSE2 +NVIDIA GeForce 210 +NVIDIA GeForce 210/PCI/SSE2 +NVIDIA GeForce 210/PCI/SSE2/3DNOW! +NVIDIA GeForce 3 +NVIDIA GeForce 305M/PCI/SSE2 +NVIDIA GeForce 310/PCI/SSE2 +NVIDIA GeForce 310/PCI/SSE2/3DNOW! +NVIDIA GeForce 310M/PCI/SSE2 +NVIDIA GeForce 315/PCI/SSE2 +NVIDIA GeForce 315/PCI/SSE2/3DNOW! +NVIDIA GeForce 315M/PCI/SSE2 +NVIDIA GeForce 320M/PCI/SSE2 +NVIDIA GeForce 4 Go +NVIDIA GeForce 4 MX +NVIDIA GeForce 4 Ti +NVIDIA GeForce 405/PCI/SSE2 +NVIDIA GeForce 6100 +NVIDIA GeForce 6100 nForce 400/PCI/SSE2/3DNOW! +NVIDIA GeForce 6100 nForce 405/PCI/SSE2 +NVIDIA GeForce 6100 nForce 405/PCI/SSE2/3DNOW! +NVIDIA GeForce 6100 nForce 420/PCI/SSE2/3DNOW! +NVIDIA GeForce 6100 nForce 430/PCI/SSE2/3DNOW! +NVIDIA GeForce 6100/PCI/SSE2/3DNOW! +NVIDIA GeForce 6150 LE/PCI/SSE2/3DNOW! +NVIDIA GeForce 6150/PCI/SSE2 +NVIDIA GeForce 6150/PCI/SSE2/3DNOW! +NVIDIA GeForce 6150SE nForce 430/PCI/SSE2 +NVIDIA GeForce 6150SE nForce 430/PCI/SSE2/3DNOW! +NVIDIA GeForce 6150SE/PCI/SSE2/3DNOW! +NVIDIA GeForce 6200 +NVIDIA GeForce 6200 A-LE/AGP/SSE/3DNOW! +NVIDIA GeForce 6200 A-LE/AGP/SSE2 +NVIDIA GeForce 6200 A-LE/AGP/SSE2/3DNOW! +NVIDIA GeForce 6200 LE/PCI/SSE2 +NVIDIA GeForce 6200 LE/PCI/SSE2/3DNOW! +NVIDIA GeForce 6200 TurboCache(TM)/PCI/SSE2 +NVIDIA GeForce 6200 TurboCache(TM)/PCI/SSE2/3DNOW! +NVIDIA GeForce 6200/AGP/SSE/3DNOW! +NVIDIA GeForce 6200/AGP/SSE2 +NVIDIA GeForce 6200/AGP/SSE2/3DNOW! +NVIDIA GeForce 6200/PCI/SSE/3DNOW! +NVIDIA GeForce 6200/PCI/SSE2 +NVIDIA GeForce 6200/PCI/SSE2/3DNOW! +NVIDIA GeForce 6200SE TurboCache(TM)/PCI/SSE2/3DNOW! +NVIDIA GeForce 6500 +NVIDIA GeForce 6500/PCI/SSE2 +NVIDIA GeForce 6600 +NVIDIA GeForce 6600 GT/AGP/SSE/3DNOW! +NVIDIA GeForce 6600 GT/AGP/SSE2 +NVIDIA GeForce 6600 GT/PCI/SSE/3DNOW! +NVIDIA GeForce 6600 GT/PCI/SSE2 +NVIDIA GeForce 6600 GT/PCI/SSE2/3DNOW! +NVIDIA GeForce 6600 LE/PCI/SSE2 +NVIDIA GeForce 6600/AGP/SSE/3DNOW! +NVIDIA GeForce 6600/AGP/SSE2 +NVIDIA GeForce 6600/AGP/SSE2/3DNOW! +NVIDIA GeForce 6600/PCI/SSE2 +NVIDIA GeForce 6600/PCI/SSE2/3DNOW! +NVIDIA GeForce 6700 +NVIDIA GeForce 6800 +NVIDIA GeForce 6800 GS/PCI/SSE2/3DNOW! +NVIDIA GeForce 6800 GT/AGP/SSE2 +NVIDIA GeForce 6800 GT/PCI/SSE2 +NVIDIA GeForce 6800 XT/AGP/SSE2 +NVIDIA GeForce 6800 XT/PCI/SSE2 +NVIDIA GeForce 6800/PCI/SSE2 +NVIDIA GeForce 6800/PCI/SSE2/3DNOW! +NVIDIA GeForce 7000 +NVIDIA GeForce 7000M +NVIDIA GeForce 7000M / nForce 610M/PCI/SSE2 +NVIDIA GeForce 7000M / nForce 610M/PCI/SSE2/3DNOW! +NVIDIA GeForce 7025 / NVIDIA nForce 630a/PCI/SSE2/3DNOW! +NVIDIA GeForce 7025 / nForce 630a/PCI/SSE2 +NVIDIA GeForce 7025 / nForce 630a/PCI/SSE2/3DNOW! +NVIDIA GeForce 7050 / NVIDIA nForce 610i/PCI/SSE2 +NVIDIA GeForce 7050 / NVIDIA nForce 620i/PCI/SSE2 +NVIDIA GeForce 7050 / nForce 610i/PCI/SSE2 +NVIDIA GeForce 7050 / nForce 620i/PCI/SSE2 +NVIDIA GeForce 7050 PV / NVIDIA nForce 630a/PCI/SSE2/3DNOW! +NVIDIA GeForce 7050 PV / nForce 630a/PCI/SSE2 +NVIDIA GeForce 7050 PV / nForce 630a/PCI/SSE2/3DNOW! +NVIDIA GeForce 7050 SE / NVIDIA nForce 630a/PCI/SSE2/3DNOW! +NVIDIA GeForce 7100 +NVIDIA GeForce 7100 / NVIDIA nForce 620i/PCI/SSE2 +NVIDIA GeForce 7100 / NVIDIA nForce 630i/PCI/SSE2 +NVIDIA GeForce 7100 / nForce 630i/PCI/SSE2 +NVIDIA GeForce 7100 GS/PCI/SSE2 +NVIDIA GeForce 7100 GS/PCI/SSE2/3DNOW! +NVIDIA GeForce 7150M / nForce 630M/PCI/SSE2 +NVIDIA GeForce 7150M / nForce 630M/PCI/SSE2/3DNOW! +NVIDIA GeForce 7300 +NVIDIA GeForce 7300 GS/PCI/SSE2 +NVIDIA GeForce 7300 GS/PCI/SSE2/3DNOW! +NVIDIA GeForce 7300 GT/AGP/SSE2 +NVIDIA GeForce 7300 GT/AGP/SSE2/3DNOW! +NVIDIA GeForce 7300 GT/PCI/SSE2 +NVIDIA GeForce 7300 GT/PCI/SSE2/3DNOW! +NVIDIA GeForce 7300 LE/PCI/SSE2 +NVIDIA GeForce 7300 LE/PCI/SSE2/3DNOW! +NVIDIA GeForce 7300 SE/7200 GS/PCI/SSE2 +NVIDIA GeForce 7300 SE/7200 GS/PCI/SSE2/3DNOW! +NVIDIA GeForce 7300 SE/PCI/SSE2 +NVIDIA GeForce 7300 SE/PCI/SSE2/3DNOW! +NVIDIA GeForce 7350 LE/PCI/SSE2 +NVIDIA GeForce 7500 +NVIDIA GeForce 7500 LE/PCI/SSE2 +NVIDIA GeForce 7500 LE/PCI/SSE2/3DNOW! +NVIDIA GeForce 7600 +NVIDIA GeForce 7600 GS/AGP/SSE2 +NVIDIA GeForce 7600 GS/AGP/SSE2/3DNOW! +NVIDIA GeForce 7600 GS/PCI/SSE2 +NVIDIA GeForce 7600 GS/PCI/SSE2/3DNOW! +NVIDIA GeForce 7600 GT/AGP/SSE/3DNOW! +NVIDIA GeForce 7600 GT/AGP/SSE2 +NVIDIA GeForce 7600 GT/PCI/SSE2 +NVIDIA GeForce 7600 GT/PCI/SSE2/3DNOW! +NVIDIA GeForce 7650 GS/PCI/SSE2 +NVIDIA GeForce 7800 +NVIDIA GeForce 7800 GS/AGP/SSE2 +NVIDIA GeForce 7800 GS/AGP/SSE2/3DNOW! +NVIDIA GeForce 7800 GT/PCI/SSE2 +NVIDIA GeForce 7800 GTX/PCI/SSE2 +NVIDIA GeForce 7800 GTX/PCI/SSE2/3DNOW! +NVIDIA GeForce 7900 +NVIDIA GeForce 7900 GS/PCI/SSE2 +NVIDIA GeForce 7900 GS/PCI/SSE2/3DNOW! +NVIDIA GeForce 7900 GT/GTO/PCI/SSE2 +NVIDIA GeForce 7900 GT/PCI/SSE2/3DNOW! +NVIDIA GeForce 7900 GTX/PCI/SSE2 +NVIDIA GeForce 7950 GT/PCI/SSE2 +NVIDIA GeForce 7950 GT/PCI/SSE2/3DNOW! +NVIDIA GeForce 8100 +NVIDIA GeForce 8100 / nForce 720a/PCI/SSE2/3DNOW! +NVIDIA GeForce 8200 +NVIDIA GeForce 8200/PCI/SSE2 +NVIDIA GeForce 8200/PCI/SSE2/3DNOW! +NVIDIA GeForce 8200M +NVIDIA GeForce 8200M G/PCI/SSE2 +NVIDIA GeForce 8200M G/PCI/SSE2/3DNOW! +NVIDIA GeForce 8300 +NVIDIA GeForce 8300 GS/PCI/SSE2 +NVIDIA GeForce 8400 +NVIDIA GeForce 8400 GS/PCI/SSE/3DNOW! +NVIDIA GeForce 8400 GS/PCI/SSE2 +NVIDIA GeForce 8400 GS/PCI/SSE2/3DNOW! +NVIDIA GeForce 8400/PCI/SSE2/3DNOW! +NVIDIA GeForce 8400GS/PCI/SSE2 +NVIDIA GeForce 8400GS/PCI/SSE2/3DNOW! +NVIDIA GeForce 8400M +NVIDIA GeForce 8400M G/PCI/SSE2 +NVIDIA GeForce 8400M G/PCI/SSE2/3DNOW! +NVIDIA GeForce 8400M GS/PCI/SSE2 +NVIDIA GeForce 8400M GS/PCI/SSE2/3DNOW! +NVIDIA GeForce 8400M GT/PCI/SSE2 +NVIDIA GeForce 8500 +NVIDIA GeForce 8500 GT/PCI/SSE2 +NVIDIA GeForce 8500 GT/PCI/SSE2/3DNOW! +NVIDIA GeForce 8600 +NVIDIA GeForce 8600 GS/PCI/SSE2 +NVIDIA GeForce 8600 GS/PCI/SSE2/3DNOW! +NVIDIA GeForce 8600 GT/PCI/SSE2 +NVIDIA GeForce 8600 GT/PCI/SSE2/3DNOW! +NVIDIA GeForce 8600 GTS/PCI/SSE2 +NVIDIA GeForce 8600 GTS/PCI/SSE2/3DNOW! +NVIDIA GeForce 8600GS/PCI/SSE2 +NVIDIA GeForce 8600M +NVIDIA GeForce 8600M GS/PCI/SSE2 +NVIDIA GeForce 8600M GS/PCI/SSE2/3DNOW! +NVIDIA GeForce 8600M GT/PCI/SSE2 +NVIDIA GeForce 8700 +NVIDIA GeForce 8700M +NVIDIA GeForce 8700M GT/PCI/SSE2 +NVIDIA GeForce 8800 +NVIDIA GeForce 8800 GS/PCI/SSE2 +NVIDIA GeForce 8800 GT/PCI/SSE2 +NVIDIA GeForce 8800 GT/PCI/SSE2/3DNOW! +NVIDIA GeForce 8800 GTS 512/PCI/SSE2 +NVIDIA GeForce 8800 GTS 512/PCI/SSE2/3DNOW! +NVIDIA GeForce 8800 GTS/PCI/SSE2 +NVIDIA GeForce 8800 GTS/PCI/SSE2/3DNOW! +NVIDIA GeForce 8800 GTX/PCI/SSE2 +NVIDIA GeForce 8800 Ultra/PCI/SSE2 +NVIDIA GeForce 8800M GTS/PCI/SSE2 +NVIDIA GeForce 8800M GTX/PCI/SSE2 +NVIDIA GeForce 9100 +NVIDIA GeForce 9100/PCI/SSE2 +NVIDIA GeForce 9100/PCI/SSE2/3DNOW! +NVIDIA GeForce 9100M +NVIDIA GeForce 9100M G/PCI/SSE2 +NVIDIA GeForce 9100M G/PCI/SSE2/3DNOW! +NVIDIA GeForce 9200 +NVIDIA GeForce 9200/PCI/SSE2 +NVIDIA GeForce 9200/PCI/SSE2/3DNOW! +NVIDIA GeForce 9200M GE/PCI/SSE2 +NVIDIA GeForce 9200M GS/PCI/SSE2 +NVIDIA GeForce 9300 +NVIDIA GeForce 9300 / nForce 730i/PCI/SSE2 +NVIDIA GeForce 9300 GE/PCI/SSE2 +NVIDIA GeForce 9300 GE/PCI/SSE2/3DNOW! +NVIDIA GeForce 9300 GS/PCI/SSE2 +NVIDIA GeForce 9300 GS/PCI/SSE2/3DNOW! +NVIDIA GeForce 9300 SE/PCI/SSE2 +NVIDIA GeForce 9300M +NVIDIA GeForce 9300M G/PCI/SSE2 +NVIDIA GeForce 9300M G/PCI/SSE2/3DNOW! +NVIDIA GeForce 9300M GS/PCI/SSE2 +NVIDIA GeForce 9300M GS/PCI/SSE2/3DNOW! +NVIDIA GeForce 9400 +NVIDIA GeForce 9400 GT/PCI/SSE2 +NVIDIA GeForce 9400 GT/PCI/SSE2/3DNOW! +NVIDIA GeForce 9400/PCI/SSE2 +NVIDIA GeForce 9400M +NVIDIA GeForce 9400M G/PCI/SSE2 +NVIDIA GeForce 9400M/PCI/SSE2 +NVIDIA GeForce 9500 +NVIDIA GeForce 9500 GS/PCI/SSE2 +NVIDIA GeForce 9500 GS/PCI/SSE2/3DNOW! +NVIDIA GeForce 9500 GT/PCI/SSE2 +NVIDIA GeForce 9500 GT/PCI/SSE2/3DNOW! +NVIDIA GeForce 9500M +NVIDIA GeForce 9500M GS/PCI/SSE2 +NVIDIA GeForce 9600 +NVIDIA GeForce 9600 GS/PCI/SSE2 +NVIDIA GeForce 9600 GSO 512/PCI/SSE2 +NVIDIA GeForce 9600 GSO/PCI/SSE2 +NVIDIA GeForce 9600 GSO/PCI/SSE2/3DNOW! +NVIDIA GeForce 9600 GT/PCI/SSE2 +NVIDIA GeForce 9600 GT/PCI/SSE2/3DNOW! +NVIDIA GeForce 9600M +NVIDIA GeForce 9600M GS/PCI/SSE2 +NVIDIA GeForce 9600M GT/PCI/SSE2 +NVIDIA GeForce 9650M GT/PCI/SSE2 +NVIDIA GeForce 9700M +NVIDIA GeForce 9700M GT/PCI/SSE2 +NVIDIA GeForce 9700M GTS/PCI/SSE2 +NVIDIA GeForce 9800 +NVIDIA GeForce 9800 GT/PCI/SSE2 +NVIDIA GeForce 9800 GT/PCI/SSE2/3DNOW! +NVIDIA GeForce 9800 GTX+/PCI/SSE2 +NVIDIA GeForce 9800 GTX+/PCI/SSE2/3DNOW! +NVIDIA GeForce 9800 GTX/9800 GTX+/PCI/SSE2 +NVIDIA GeForce 9800 GTX/PCI/SSE2 +NVIDIA GeForce 9800 GX2/PCI/SSE2 +NVIDIA GeForce 9800M +NVIDIA GeForce 9800M GS/PCI/SSE2 +NVIDIA GeForce 9800M GT/PCI/SSE2 +NVIDIA GeForce 9800M GTS/PCI/SSE2 +NVIDIA GeForce FX 5100 +NVIDIA GeForce FX 5100/AGP/SSE/3DNOW! +NVIDIA GeForce FX 5200 +NVIDIA GeForce FX 5200/AGP/SSE +NVIDIA GeForce FX 5200/AGP/SSE/3DNOW! +NVIDIA GeForce FX 5200/AGP/SSE2 +NVIDIA GeForce FX 5200/AGP/SSE2/3DNOW! +NVIDIA GeForce FX 5200/PCI/SSE2 +NVIDIA GeForce FX 5200/PCI/SSE2/3DNOW! +NVIDIA GeForce FX 5200LE/AGP/SSE2 +NVIDIA GeForce FX 5500 +NVIDIA GeForce FX 5500/AGP/SSE/3DNOW! +NVIDIA GeForce FX 5500/AGP/SSE2 +NVIDIA GeForce FX 5500/AGP/SSE2/3DNOW! +NVIDIA GeForce FX 5500/PCI/SSE2 +NVIDIA GeForce FX 5500/PCI/SSE2/3DNOW! +NVIDIA GeForce FX 5600 +NVIDIA GeForce FX 5600/AGP/SSE2 +NVIDIA GeForce FX 5600/AGP/SSE2/3DNOW! +NVIDIA GeForce FX 5600XT/AGP/SSE2/3DNOW! +NVIDIA GeForce FX 5700 +NVIDIA GeForce FX 5700/AGP/SSE/3DNOW! +NVIDIA GeForce FX 5700LE/AGP/SSE +NVIDIA GeForce FX 5700LE/AGP/SSE/3DNOW! +NVIDIA GeForce FX 5800 +NVIDIA GeForce FX 5900 +NVIDIA GeForce FX 5900/AGP/SSE2 +NVIDIA GeForce FX 5900XT/AGP/SSE2 +NVIDIA GeForce FX Go5100 +NVIDIA GeForce FX Go5100/AGP/SSE2 +NVIDIA GeForce FX Go5200 +NVIDIA GeForce FX Go5200/AGP/SSE2 +NVIDIA GeForce FX Go5300 +NVIDIA GeForce FX Go5600 +NVIDIA GeForce FX Go5600/AGP/SSE2 +NVIDIA GeForce FX Go5650/AGP/SSE2 +NVIDIA GeForce FX Go5700 +NVIDIA GeForce FX Go5xxx/AGP/SSE2 +NVIDIA GeForce G 103M/PCI/SSE2 +NVIDIA GeForce G 105M/PCI/SSE2 +NVIDIA GeForce G 110M/PCI/SSE2 +NVIDIA GeForce G100/PCI/SSE2 +NVIDIA GeForce G100/PCI/SSE2/3DNOW! +NVIDIA GeForce G102M/PCI/SSE2 +NVIDIA GeForce G105M/PCI/SSE2 +NVIDIA GeForce G200/PCI/SSE2 +NVIDIA GeForce G205M/PCI/SSE2 +NVIDIA GeForce G210/PCI/SSE2 +NVIDIA GeForce G210/PCI/SSE2/3DNOW! +NVIDIA GeForce G210M/PCI/SSE2 +NVIDIA GeForce G310M/PCI/SSE2 +NVIDIA GeForce GT 120/PCI/SSE2 +NVIDIA GeForce GT 120/PCI/SSE2/3DNOW! +NVIDIA GeForce GT 120M/PCI/SSE2 +NVIDIA GeForce GT 130M/PCI/SSE2 +NVIDIA GeForce GT 140/PCI/SSE2 +NVIDIA GeForce GT 220/PCI/SSE2 +NVIDIA GeForce GT 220/PCI/SSE2/3DNOW! +NVIDIA GeForce GT 220M/PCI/SSE2 +NVIDIA GeForce GT 230/PCI/SSE2 +NVIDIA GeForce GT 230M/PCI/SSE2 +NVIDIA GeForce GT 240 +NVIDIA GeForce GT 240/PCI/SSE2 +NVIDIA GeForce GT 240/PCI/SSE2/3DNOW! +NVIDIA GeForce GT 240M/PCI/SSE2 +NVIDIA GeForce GT 320/PCI/SSE2 +NVIDIA GeForce GT 320M/PCI/SSE2 +NVIDIA GeForce GT 325M/PCI/SSE2 +NVIDIA GeForce GT 330/PCI/SSE2 +NVIDIA GeForce GT 330/PCI/SSE2/3DNOW! +NVIDIA GeForce GT 330M/PCI/SSE2 +NVIDIA GeForce GT 335M/PCI/SSE2 +NVIDIA GeForce GT 340/PCI/SSE2 +NVIDIA GeForce GT 340/PCI/SSE2/3DNOW! +NVIDIA GeForce GT 415M/PCI/SSE2 +NVIDIA GeForce GT 420/PCI/SSE2 +NVIDIA GeForce GT 420M/PCI/SSE2 +NVIDIA GeForce GT 425M/PCI/SSE2 +NVIDIA GeForce GT 430/PCI/SSE2 +NVIDIA GeForce GT 430/PCI/SSE2/3DNOW! +NVIDIA GeForce GT 435M/PCI/SSE2 +NVIDIA GeForce GT 440/PCI/SSE2 +NVIDIA GeForce GT 440/PCI/SSE2/3DNOW! +NVIDIA GeForce GT 445M/PCI/SSE2 +NVIDIA GeForce GT 520M/PCI/SSE2 +NVIDIA GeForce GT 525M/PCI/SSE2 +NVIDIA GeForce GT 540M/PCI/SSE2 +NVIDIA GeForce GT 550M/PCI/SSE2 +NVIDIA GeForce GT 555M/PCI/SSE2 +NVIDIA GeForce GTS 150/PCI/SSE2 +NVIDIA GeForce GTS 160M/PCI/SSE2 +NVIDIA GeForce GTS 240/PCI/SSE2 +NVIDIA GeForce GTS 250/PCI/SSE2 +NVIDIA GeForce GTS 250/PCI/SSE2/3DNOW! +NVIDIA GeForce GTS 250M/PCI/SSE2 +NVIDIA GeForce GTS 350M/PCI/SSE2 +NVIDIA GeForce GTS 360M/PCI/SSE2 +NVIDIA GeForce GTS 450/PCI/SSE2 +NVIDIA GeForce GTS 450/PCI/SSE2/3DNOW! +NVIDIA GeForce GTS 455/PCI/SSE2 +NVIDIA GeForce GTX 260/PCI/SSE2 +NVIDIA GeForce GTX 260/PCI/SSE2/3DNOW! +NVIDIA GeForce GTX 260M/PCI/SSE2 +NVIDIA GeForce GTX 275/PCI/SSE2 +NVIDIA GeForce GTX 280 +NVIDIA GeForce GTX 280/PCI/SSE2 +NVIDIA GeForce GTX 280M/PCI/SSE2 +NVIDIA GeForce GTX 285/PCI/SSE2 +NVIDIA GeForce GTX 295/PCI/SSE2 +NVIDIA GeForce GTX 460 SE/PCI/SSE2 +NVIDIA GeForce GTX 460 SE/PCI/SSE2/3DNOW! +NVIDIA GeForce GTX 460/PCI/SSE2 +NVIDIA GeForce GTX 460/PCI/SSE2/3DNOW! +NVIDIA GeForce GTX 460M/PCI/SSE2 +NVIDIA GeForce GTX 465/PCI/SSE2 +NVIDIA GeForce GTX 465/PCI/SSE2/3DNOW! +NVIDIA GeForce GTX 470/PCI/SSE2 +NVIDIA GeForce GTX 470/PCI/SSE2/3DNOW! +NVIDIA GeForce GTX 480/PCI/SSE2 +NVIDIA GeForce GTX 550 Ti/PCI/SSE2 +NVIDIA GeForce GTX 550 Ti/PCI/SSE2/3DNOW! +NVIDIA GeForce GTX 560 Ti/PCI/SSE2 +NVIDIA GeForce GTX 560 Ti/PCI/SSE2/3DNOW! +NVIDIA GeForce GTX 560/PCI/SSE2 +NVIDIA GeForce GTX 570/PCI/SSE2 +NVIDIA GeForce GTX 570/PCI/SSE2/3DNOW! +NVIDIA GeForce GTX 580/PCI/SSE2 +NVIDIA GeForce GTX 580/PCI/SSE2/3DNOW! +NVIDIA GeForce GTX 580M/PCI/SSE2 +NVIDIA GeForce GTX 590/PCI/SSE2 +NVIDIA GeForce Go 6 +NVIDIA GeForce Go 6100 +NVIDIA GeForce Go 6100/PCI/SSE2 +NVIDIA GeForce Go 6100/PCI/SSE2/3DNOW! +NVIDIA GeForce Go 6150/PCI/SSE2 +NVIDIA GeForce Go 6150/PCI/SSE2/3DNOW! +NVIDIA GeForce Go 6200 +NVIDIA GeForce Go 6200/PCI/SSE2 +NVIDIA GeForce Go 6400 +NVIDIA GeForce Go 6400/PCI/SSE2 +NVIDIA GeForce Go 6600 +NVIDIA GeForce Go 6600/PCI/SSE2 +NVIDIA GeForce Go 6800 +NVIDIA GeForce Go 6800 Ultra/PCI/SSE2 +NVIDIA GeForce Go 6800/PCI/SSE2 +NVIDIA GeForce Go 7200 +NVIDIA GeForce Go 7200/PCI/SSE2 +NVIDIA GeForce Go 7200/PCI/SSE2/3DNOW! +NVIDIA GeForce Go 7300 +NVIDIA GeForce Go 7300/PCI/SSE2 +NVIDIA GeForce Go 7300/PCI/SSE2/3DNOW! +NVIDIA GeForce Go 7400 +NVIDIA GeForce Go 7400/PCI/SSE2 +NVIDIA GeForce Go 7400/PCI/SSE2/3DNOW! +NVIDIA GeForce Go 7600 +NVIDIA GeForce Go 7600/PCI/SSE2 +NVIDIA GeForce Go 7600/PCI/SSE2/3DNOW! +NVIDIA GeForce Go 7700 +NVIDIA GeForce Go 7800 +NVIDIA GeForce Go 7800 GTX/PCI/SSE2 +NVIDIA GeForce Go 7900 +NVIDIA GeForce Go 7900 GS/PCI/SSE2 +NVIDIA GeForce Go 7900 GTX/PCI/SSE2 +NVIDIA GeForce Go 7950 GTX/PCI/SSE2 +NVIDIA GeForce PCX +NVIDIA GeForce2 GTS/AGP/SSE +NVIDIA GeForce2 MX/AGP/3DNOW! +NVIDIA GeForce2 MX/AGP/SSE/3DNOW! +NVIDIA GeForce2 MX/AGP/SSE2 +NVIDIA GeForce2 MX/PCI/SSE2 +NVIDIA GeForce3/AGP/SSE/3DNOW! +NVIDIA GeForce3/AGP/SSE2 +NVIDIA GeForce4 420 Go 32M/AGP/SSE2 +NVIDIA GeForce4 420 Go 32M/AGP/SSE2/3DNOW! +NVIDIA GeForce4 420 Go 32M/PCI/SSE2/3DNOW! +NVIDIA GeForce4 440 Go 64M/AGP/SSE2/3DNOW! +NVIDIA GeForce4 460 Go/AGP/SSE2 +NVIDIA GeForce4 MX 4000/AGP/SSE/3DNOW! +NVIDIA GeForce4 MX 4000/AGP/SSE2 +NVIDIA GeForce4 MX 4000/PCI/3DNOW! +NVIDIA GeForce4 MX 4000/PCI/SSE/3DNOW! +NVIDIA GeForce4 MX 4000/PCI/SSE2 +NVIDIA GeForce4 MX 420/AGP/SSE/3DNOW! +NVIDIA GeForce4 MX 420/AGP/SSE2 +NVIDIA GeForce4 MX 440 with AGP8X/AGP/SSE2 +NVIDIA GeForce4 MX 440/AGP/SSE2 +NVIDIA GeForce4 MX 440/AGP/SSE2/3DNOW! +NVIDIA GeForce4 MX 440SE with AGP8X/AGP/SSE2 +NVIDIA GeForce4 MX Integrated GPU/AGP/SSE/3DNOW! +NVIDIA GeForce4 Ti 4200 with AGP8X/AGP/SSE +NVIDIA GeForce4 Ti 4200/AGP/SSE/3DNOW! +NVIDIA GeForce4 Ti 4400/AGP/SSE2 +NVIDIA Generic +NVIDIA ION LE/PCI/SSE2 +NVIDIA ION/PCI/SSE2 +NVIDIA ION/PCI/SSE2/3DNOW! +NVIDIA MCP61/PCI/SSE2 +NVIDIA MCP61/PCI/SSE2/3DNOW! +NVIDIA MCP73/PCI/SSE2 +NVIDIA MCP79MH/PCI/SSE2 +NVIDIA MCP79MX/PCI/SSE2 +NVIDIA MCP7A-O/PCI/SSE2 +NVIDIA MCP7A-S/PCI/SSE2 +NVIDIA MCP89-EPT/PCI/SSE2 +NVIDIA N10M-GE1/PCI/SSE2 +NVIDIA N10P-GE1/PCI/SSE2 +NVIDIA N10P-GV2/PCI/SSE2 +NVIDIA N11M-GE1/PCI/SSE2 +NVIDIA N11M-GE2/PCI/SSE2 +NVIDIA N12E-GS-A1/PCI/SSE2 +NVIDIA NB9M-GE/PCI/SSE2 +NVIDIA NB9M-GE1/PCI/SSE2 +NVIDIA NB9M-GS/PCI/SSE2 +NVIDIA NB9M-NS/PCI/SSE2 +NVIDIA NB9P-GE1/PCI/SSE2 +NVIDIA NB9P-GS/PCI/SSE2 +NVIDIA NV17/AGP/3DNOW! +NVIDIA NV17/AGP/SSE2 +NVIDIA NV34 +NVIDIA NV35 +NVIDIA NV36/AGP/SSE/3DNOW! +NVIDIA NV36/AGP/SSE2 +NVIDIA NV41/PCI/SSE2 +NVIDIA NV43 +NVIDIA NV44 +NVIDIA NVIDIA GeForce 210 OpenGL Engine +NVIDIA NVIDIA GeForce 320M OpenGL Engine +NVIDIA NVIDIA GeForce 7300 GT OpenGL Engine +NVIDIA NVIDIA GeForce 7600 GT OpenGL Engine +NVIDIA NVIDIA GeForce 8600M GT OpenGL Engine +NVIDIA NVIDIA GeForce 8800 GS OpenGL Engine +NVIDIA NVIDIA GeForce 8800 GT OpenGL Engine +NVIDIA NVIDIA GeForce 9400 OpenGL Engine +NVIDIA NVIDIA GeForce 9400M OpenGL Engine +NVIDIA NVIDIA GeForce 9500 GT OpenGL Engine +NVIDIA NVIDIA GeForce 9600M GT OpenGL Engine +NVIDIA NVIDIA GeForce GT 120 OpenGL Engine +NVIDIA NVIDIA GeForce GT 130 OpenGL Engine +NVIDIA NVIDIA GeForce GT 220 OpenGL Engine +NVIDIA NVIDIA GeForce GT 230M OpenGL Engine +NVIDIA NVIDIA GeForce GT 240M OpenGL Engine +NVIDIA NVIDIA GeForce GT 330M OpenGL Engine +NVIDIA NVIDIA GeForce GT 420M OpenGL Engine +NVIDIA NVIDIA GeForce GT 425M OpenGL Engine +NVIDIA NVIDIA GeForce GT 430 OpenGL Engine +NVIDIA NVIDIA GeForce GT 440 OpenGL Engine +NVIDIA NVIDIA GeForce GT 540M OpenGL Engine +NVIDIA NVIDIA GeForce GTS 240 OpenGL Engine +NVIDIA NVIDIA GeForce GTS 250 OpenGL Engine +NVIDIA NVIDIA GeForce GTS 450 OpenGL Engine +NVIDIA NVIDIA GeForce GTX 285 OpenGL Engine +NVIDIA NVIDIA GeForce GTX 460 OpenGL Engine +NVIDIA NVIDIA GeForce GTX 460M OpenGL Engine +NVIDIA NVIDIA GeForce GTX 465 OpenGL Engine +NVIDIA NVIDIA GeForce GTX 470 OpenGL Engine +NVIDIA NVIDIA GeForce GTX 480 OpenGL Engine +NVIDIA NVIDIA GeForce Pre-Release ION OpenGL Engine +NVIDIA NVIDIA GeForce4 OpenGL Engine +NVIDIA NVIDIA NV34MAP OpenGL Engine +NVIDIA NVIDIA Quadro 4000 OpenGL Engine +NVIDIA NVIDIA Quadro FX 4800 OpenGL Engine +NVIDIA NVS 2100M/PCI/SSE2 +NVIDIA NVS 300/PCI/SSE2 +NVIDIA NVS 3100M/PCI/SSE2 +NVIDIA NVS 4100/PCI/SSE2/3DNOW! +NVIDIA NVS 4200M/PCI/SSE2 +NVIDIA NVS 5100M/PCI/SSE2 +NVIDIA PCI +NVIDIA Quadro 2000/PCI/SSE2 +NVIDIA Quadro 4000 +NVIDIA Quadro 4000 OpenGL Engine +NVIDIA Quadro 4000/PCI/SSE2 +NVIDIA Quadro 5000/PCI/SSE2 +NVIDIA Quadro 5000M/PCI/SSE2 +NVIDIA Quadro 600 +NVIDIA Quadro 600/PCI/SSE2 +NVIDIA Quadro 600/PCI/SSE2/3DNOW! +NVIDIA Quadro 6000 +NVIDIA Quadro 6000/PCI/SSE2 +NVIDIA Quadro CX/PCI/SSE2 +NVIDIA Quadro DCC +NVIDIA Quadro FX +NVIDIA Quadro FX 1100/AGP/SSE2 +NVIDIA Quadro FX 1400/PCI/SSE2 +NVIDIA Quadro FX 1500 +NVIDIA Quadro FX 1500M/PCI/SSE2 +NVIDIA Quadro FX 1600M/PCI/SSE2 +NVIDIA Quadro FX 1700 +NVIDIA Quadro FX 1700M/PCI/SSE2 +NVIDIA Quadro FX 1800 +NVIDIA Quadro FX 1800/PCI/SSE2 +NVIDIA Quadro FX 1800M/PCI/SSE2 +NVIDIA Quadro FX 2500M/PCI/SSE2 +NVIDIA Quadro FX 2700M/PCI/SSE2 +NVIDIA Quadro FX 2800M/PCI/SSE2 +NVIDIA Quadro FX 3400 +NVIDIA Quadro FX 3450 +NVIDIA Quadro FX 3450/4000 SDI/PCI/SSE2 +NVIDIA Quadro FX 3500 +NVIDIA Quadro FX 3500M/PCI/SSE2 +NVIDIA Quadro FX 360M/PCI/SSE2 +NVIDIA Quadro FX 370 +NVIDIA Quadro FX 370/PCI/SSE2 +NVIDIA Quadro FX 3700 +NVIDIA Quadro FX 3700M/PCI/SSE2 +NVIDIA Quadro FX 370M/PCI/SSE2 +NVIDIA Quadro FX 3800 +NVIDIA Quadro FX 3800M/PCI/SSE2 +NVIDIA Quadro FX 4500 +NVIDIA Quadro FX 4600 +NVIDIA Quadro FX 4800 +NVIDIA Quadro FX 4800/PCI/SSE2 +NVIDIA Quadro FX 560 +NVIDIA Quadro FX 5600 +NVIDIA Quadro FX 570 +NVIDIA Quadro FX 570/PCI/SSE2 +NVIDIA Quadro FX 570M/PCI/SSE2 +NVIDIA Quadro FX 580/PCI/SSE2 +NVIDIA Quadro FX 770M/PCI/SSE2 +NVIDIA Quadro FX 880M +NVIDIA Quadro FX 880M/PCI/SSE2 +NVIDIA Quadro FX Go700/AGP/SSE2 +NVIDIA Quadro NVS +NVIDIA Quadro NVS 110M/PCI/SSE2 +NVIDIA Quadro NVS 130M/PCI/SSE2 +NVIDIA Quadro NVS 135M/PCI/SSE2 +NVIDIA Quadro NVS 140M/PCI/SSE2 +NVIDIA Quadro NVS 150M/PCI/SSE2 +NVIDIA Quadro NVS 160M/PCI/SSE2 +NVIDIA Quadro NVS 210S/PCI/SSE2/3DNOW! +NVIDIA Quadro NVS 285/PCI/SSE2 +NVIDIA Quadro NVS 290/PCI/SSE2 +NVIDIA Quadro NVS 295/PCI/SSE2 +NVIDIA Quadro NVS 320M/PCI/SSE2 +NVIDIA Quadro NVS 55/280 PCI/PCI/SSE2 +NVIDIA Quadro NVS/PCI/SSE2 +NVIDIA Quadro PCI-E Series/PCI/SSE2/3DNOW! +NVIDIA Quadro VX 200/PCI/SSE2 +NVIDIA Quadro/AGP/SSE2 +NVIDIA Quadro2 +NVIDIA Quadro4 +NVIDIA RIVA TNT +NVIDIA RIVA TNT2/AGP/SSE2 +NVIDIA RIVA TNT2/PCI/3DNOW! +NVIDIA nForce +NVIDIA unknown board/AGP/SSE2 +NVIDIA unknown board/PCI/SSE2 +NVIDIA unknown board/PCI/SSE2/3DNOW! +Parallels and ATI Technologies Inc. Parallels using ATI Radeon HD 5670 OpenGL Engine +Parallels and ATI Technologies Inc. Parallels using ATI Radeon HD 5750 OpenGL Engine +Parallels and ATI Technologies Inc. Parallels using ATI Radeon HD 5770 OpenGL Engine +Parallels and ATI Technologies Inc. Parallels using ATI Radeon HD 6490M OpenGL Engine +Parallels and ATI Technologies Inc. Parallels using ATI Radeon HD 6750M OpenGL Engine +Parallels and Intel Inc. 3D-Analyze v2.3 - http://www.tommti-systems.com +Parallels and Intel Inc. Parallels using Intel HD Graphics 3000 OpenGL Engine +Parallels and NVIDIA Parallels using NVIDIA GeForce 320M OpenGL Engine +Parallels and NVIDIA Parallels using NVIDIA GeForce 9400 OpenGL Engine +Parallels and NVIDIA Parallels using NVIDIA GeForce GT 120 OpenGL Engine +Parallels and NVIDIA Parallels using NVIDIA GeForce GT 330M OpenGL Engine +Radeon RV350 on Gallium +S3 +S3 Graphics VIA/S3G UniChrome IGP/MMX/K3D +S3 Graphics VIA/S3G UniChrome Pro IGP/MMX/SSE +S3 Graphics, Incorporated ProSavage/Twister +S3 Graphics, Incorporated S3 Graphics Chrome9 HC +S3 Graphics, Incorporated S3 Graphics DeltaChrome +S3 Graphics, Incorporated VIA Chrome9 HC IGP +SiS +SiS 661 VGA +SiS 662 VGA +SiS 741 VGA +SiS 760 VGA +SiS 761GX VGA +SiS Mirage Graphics3 +Trident +Tungsten Graphics +Tungsten Graphics, Inc Mesa DRI 865G GEM 20091221 2009Q4 x86/MMX/SSE2 +Tungsten Graphics, Inc Mesa DRI 865G GEM 20100330 DEVELOPMENT x86/MMX/SSE2 +Tungsten Graphics, Inc Mesa DRI 915G GEM 20091221 2009Q4 x86/MMX/SSE2 +Tungsten Graphics, Inc Mesa DRI 915G GEM 20100330 DEVELOPMENT x86/MMX/SSE2 +Tungsten Graphics, Inc Mesa DRI 915GM GEM 20090712 2009Q2 RC3 x86/MMX/SSE2 +Tungsten Graphics, Inc Mesa DRI 915GM GEM 20091221 2009Q4 x86/MMX/SSE2 +Tungsten Graphics, Inc Mesa DRI 915GM GEM 20100330 DEVELOPMENT x86/MMX/SSE2 +Tungsten Graphics, Inc Mesa DRI 945G +Tungsten Graphics, Inc Mesa DRI 945G GEM 20091221 2009Q4 x86/MMX/SSE2 +Tungsten Graphics, Inc Mesa DRI 945G GEM 20100330 DEVELOPMENT +Tungsten Graphics, Inc Mesa DRI 945G GEM 20100330 DEVELOPMENT x86/MMX/SSE2 +Tungsten Graphics, Inc Mesa DRI 945GM GEM 20090712 2009Q2 RC3 x86/MMX/SSE2 +Tungsten Graphics, Inc Mesa DRI 945GM GEM 20091221 2009Q4 x86/MMX/SSE2 +Tungsten Graphics, Inc Mesa DRI 945GM GEM 20100328 2010Q1 x86/MMX/SSE2 +Tungsten Graphics, Inc Mesa DRI 945GM GEM 20100330 DEVELOPMENT x86/MMX/SSE2 +Tungsten Graphics, Inc Mesa DRI 945GME x86/MMX/SSE2 +Tungsten Graphics, Inc Mesa DRI 945GME 20061017 +Tungsten Graphics, Inc Mesa DRI 945GME GEM 20090712 2009Q2 RC3 x86/MMX/SSE2 +Tungsten Graphics, Inc Mesa DRI 945GME GEM 20091221 2009Q4 x86/MMX/SSE2 +Tungsten Graphics, Inc Mesa DRI 945GME GEM 20100330 DEVELOPMENT x86/MMX/SSE2 +Tungsten Graphics, Inc Mesa DRI 965GM GEM 20090326 2009Q1 RC2 x86/MMX/SSE2 +Tungsten Graphics, Inc Mesa DRI 965GM GEM 20090712 2009Q2 RC3 x86/MMX/SSE2 +Tungsten Graphics, Inc Mesa DRI 965GM GEM 20091221 2009Q4 x86/MMX/SSE2 +Tungsten Graphics, Inc Mesa DRI 965GM GEM 20100330 DEVELOPMENT x86/MMX/SSE2 +Tungsten Graphics, Inc Mesa DRI G33 20061017 x86/MMX/SSE2 +Tungsten Graphics, Inc Mesa DRI G33 GEM 20090712 2009Q2 RC3 x86/MMX/SSE2 +Tungsten Graphics, Inc Mesa DRI G33 GEM 20091221 2009Q4 x86/MMX/SSE2 +Tungsten Graphics, Inc Mesa DRI G41 GEM 20091221 2009Q4 x86/MMX/SSE2 +Tungsten Graphics, Inc Mesa DRI G41 GEM 20100330 DEVELOPMENT x86/MMX/SSE2 +Tungsten Graphics, Inc Mesa DRI GMA500 20081116 - 5.0.1.0046 x86/MMX/SSE2 +Tungsten Graphics, Inc Mesa DRI IGD GEM 20091221 2009Q4 x86/MMX/SSE2 +Tungsten Graphics, Inc Mesa DRI IGD GEM 20100330 DEVELOPMENT +Tungsten Graphics, Inc Mesa DRI IGD GEM 20100330 DEVELOPMENT x86/MMX/SSE2 +Tungsten Graphics, Inc Mesa DRI IGDNG_D GEM 20091221 2009Q4 x86/MMX/SSE2 +Tungsten Graphics, Inc Mesa DRI Ironlake Desktop GEM 20100330 DEVELOPMENT x86/MMX/SSE2 +Tungsten Graphics, Inc Mesa DRI Ironlake Mobile GEM 20100330 DEVELOPMENT x86/MMX/SSE2 +Tungsten Graphics, Inc Mesa DRI Mobile Intelå¨ GM45 Express Chipset 20080716 x86/MMX/SSE2 +Tungsten Graphics, Inc Mesa DRI Mobile Intelå¨ GM45 Express Chipset GEM 20090712 2009Q2 RC3 x86/MMX/SSE2 +Tungsten Graphics, Inc Mesa DRI Mobile Intelå¨ GM45 Express Chipset GEM 20091221 2009Q4 x86/MMX/SSE2 +Tungsten Graphics, Inc Mesa DRI Mobile Intelå¨ GM45 Express Chipset GEM 20100328 2010Q1 +Tungsten Graphics, Inc Mesa DRI Mobile Intelå¨ GM45 Express Chipset GEM 20100330 DEVELOPMENT +Tungsten Graphics, Inc Mesa DRI Mobile Intelå¨ GM45 Express Chipset GEM 20100330 DEVELOPMENT x86/MMX/SSE2 +Tungsten Graphics, Inc. Mesa DRI R200 (RV280 5964) 20090101 x86/MMX+/3DNow!+/SSE2 TCL DRI2 +VIA +VMware, Inc. Gallium 0.3 on SVGA3D; build: RELEASE; +VMware, Inc. Gallium 0.4 on i915 (chipset: 945GM) +VMware, Inc. Gallium 0.4 on llvmpipe +VMware, Inc. Gallium 0.4 on softpipe +X.Org Gallium 0.4 on AMD BARTS +X.Org Gallium 0.4 on AMD CEDAR +X.Org Gallium 0.4 on AMD HEMLOCK +X.Org Gallium 0.4 on AMD JUNIPER +X.Org Gallium 0.4 on AMD REDWOOD +X.Org Gallium 0.4 on AMD RS780 +X.Org Gallium 0.4 on AMD RS880 +X.Org Gallium 0.4 on AMD RV610 +X.Org Gallium 0.4 on AMD RV620 +X.Org Gallium 0.4 on AMD RV630 +X.Org Gallium 0.4 on AMD RV635 +X.Org Gallium 0.4 on AMD RV710 +X.Org Gallium 0.4 on AMD RV730 +X.Org Gallium 0.4 on AMD RV740 +X.Org Gallium 0.4 on AMD RV770 +X.Org R300 Project Gallium 0.4 on ATI R300 +X.Org R300 Project Gallium 0.4 on ATI R580 +X.Org R300 Project Gallium 0.4 on ATI RC410 +X.Org R300 Project Gallium 0.4 on ATI RS482 +X.Org R300 Project Gallium 0.4 on ATI RS600 +X.Org R300 Project Gallium 0.4 on ATI RS690 +X.Org R300 Project Gallium 0.4 on ATI RV350 +X.Org R300 Project Gallium 0.4 on ATI RV370 +X.Org R300 Project Gallium 0.4 on ATI RV410 +X.Org R300 Project Gallium 0.4 on ATI RV515 +X.Org R300 Project Gallium 0.4 on ATI RV530 +X.Org R300 Project Gallium 0.4 on ATI RV570 +X.Org R300 Project Gallium 0.4 on R420 +X.Org R300 Project Gallium 0.4 on R580 +X.Org R300 Project Gallium 0.4 on RC410 +X.Org R300 Project Gallium 0.4 on RS480 +X.Org R300 Project Gallium 0.4 on RS482 +X.Org R300 Project Gallium 0.4 on RS600 +X.Org R300 Project Gallium 0.4 on RS690 +X.Org R300 Project Gallium 0.4 on RS740 +X.Org R300 Project Gallium 0.4 on RV350 +X.Org R300 Project Gallium 0.4 on RV370 +X.Org R300 Project Gallium 0.4 on RV410 +X.Org R300 Project Gallium 0.4 on RV515 +X.Org R300 Project Gallium 0.4 on RV530 +XGI +nouveau Gallium 0.4 on NV34 +nouveau Gallium 0.4 on NV36 +nouveau Gallium 0.4 on NV46 +nouveau Gallium 0.4 on NV49 +nouveau Gallium 0.4 on NV4A +nouveau Gallium 0.4 on NV4B +nouveau Gallium 0.4 on NV4E +nouveau Gallium 0.4 on NV50 +nouveau Gallium 0.4 on NV84 +nouveau Gallium 0.4 on NV86 +nouveau Gallium 0.4 on NV92 +nouveau Gallium 0.4 on NV94 +nouveau Gallium 0.4 on NV96 +nouveau Gallium 0.4 on NV98 +nouveau Gallium 0.4 on NVA0 +nouveau Gallium 0.4 on NVA3 +nouveau Gallium 0.4 on NVA5 +nouveau Gallium 0.4 on NVA8 +nouveau Gallium 0.4 on NVAA +nouveau Gallium 0.4 on NVAC diff --git a/indra/newview/tests/llagentaccess_test.cpp b/indra/newview/tests/llagentaccess_test.cpp index 42872d85fb..c970d79975 100644 --- a/indra/newview/tests/llagentaccess_test.cpp +++ b/indra/newview/tests/llagentaccess_test.cpp @@ -2,33 +2,29 @@ * @file llagentaccess_test.cpp * @brief LLAgentAccess tests * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ + +#include "linden_common.h" #include "../test/lltut.h" #include "../llagentaccess.h" @@ -78,7 +74,7 @@ namespace tut typedef test_group<agentaccess> agentaccess_t; typedef agentaccess_t::object agentaccess_object_t; - tut::agentaccess_t tut_agentaccess("agentaccess"); + tut::agentaccess_t tut_agentaccess("LLAgentAccess"); template<> template<> void agentaccess_object_t::test<1>() diff --git a/indra/newview/tests/llcapabilitylistener_test.cpp b/indra/newview/tests/llcapabilitylistener_test.cpp index f66ae9404f..2ad08dc1f3 100644 --- a/indra/newview/tests/llcapabilitylistener_test.cpp +++ b/indra/newview/tests/llcapabilitylistener_test.cpp @@ -4,8 +4,25 @@ * @date 2008-12-31 * @brief Test for llcapabilitylistener.cpp. * - * $LicenseInfo:firstyear=2008&license=viewergpl$ - * Copyright (c) 2008, Linden Research, Inc. + * $LicenseInfo:firstyear=2008&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -24,9 +41,10 @@ #include "../test/lltut.h" #include "../llcapabilityprovider.h" #include "lluuid.h" -#include "llerrorcontrol.h" #include "tests/networkio.h" #include "tests/commtest.h" +#include "tests/wrapllerrs.h" +#include "message.h" #include "stringize.h" #if defined(LL_WINDOWS) @@ -54,7 +72,7 @@ struct TestCapabilityProvider: public LLCapabilityProvider { mCaps[cap] = url; } - LLHost getHost() const { return mHost; } + const LLHost& getHost() const { return mHost; } std::string getDescription() const { return "TestCapabilityProvider"; } LLHost mHost; @@ -96,6 +114,7 @@ namespace tut regionListener("testCapabilityListener", NULL, provider, LLUUID(), LLUUID()), regionPump(regionListener.getCapAPI()) { + LLCurl::initClass(); provider.setCapability("good", server + "capability-test"); provider.setCapability("fail", server + "fail"); } @@ -104,28 +123,6 @@ namespace tut typedef llcapears_group::object llcapears_object; llcapears_group llsdmgr("llcapabilitylistener"); - struct CaptureError: public LLError::OverrideFatalFunction - { - CaptureError(): - LLError::OverrideFatalFunction(boost::bind(&CaptureError::operator(), this, _1)) - { - LLError::setPrintLocation(false); - } - - struct FatalException: public std::runtime_error - { - FatalException(const std::string& what): std::runtime_error(what) {} - }; - - void operator()(const std::string& message) - { - error = message; - throw FatalException(message); - } - - std::string error; - }; - template<> template<> void llcapears_object::test<1>() { @@ -137,10 +134,10 @@ namespace tut std::string threw; try { - CaptureError capture; + WrapLL_ERRS capture; regionPump.post(request); } - catch (const CaptureError::FatalException& e) + catch (const WrapLL_ERRS::FatalException& e) { threw = e.what(); } @@ -184,10 +181,10 @@ namespace tut std::string threw; try { - CaptureError capture; + WrapLL_ERRS capture; regionPump.post(request); } - catch (const CaptureError::FatalException& e) + catch (const WrapLL_ERRS::FatalException& e) { threw = e.what(); } @@ -246,10 +243,10 @@ namespace tut std::string threw; try { - CaptureError capture; + WrapLL_ERRS capture; regionPump.post(request); } - catch (const CaptureError::FatalException& e) + catch (const WrapLL_ERRS::FatalException& e) { threw = e.what(); } diff --git a/indra/newview/tests/lldateutil_test.cpp b/indra/newview/tests/lldateutil_test.cpp new file mode 100644 index 0000000000..47353962e1 --- /dev/null +++ b/indra/newview/tests/lldateutil_test.cpp @@ -0,0 +1,196 @@ +/** + * @file lldateutil_test.cpp + * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "linden_common.h" + +#include "../test/lltut.h" + +#include "../lldateutil.h" + +#include "lldate.h" +#include "llstring.h" // LLStringUtil::format() +#include "lltrans.h" +#include "llui.h" + +#include <map> + + +// Baked-in return values for getString() +std::map< std::string, std::string > gString; + +// Baked-in return values for getCountString() +// map of pairs of input xml_desc and integer count +typedef std::pair< std::string, int > count_string_t; +std::map< count_string_t, std::string > gCountString; + +std::string LLTrans::getString(const std::string &xml_desc, const LLStringUtil::format_map_t& args) +{ + std::string text = gString[xml_desc]; + LLStringUtil::format(text, args); + return text; +} + +std::string LLTrans::getCountString(const std::string& language, const std::string& xml_desc, S32 count) +{ + count_string_t key(xml_desc, count); + if (gCountString.find(key) == gCountString.end()) + { + return std::string("Couldn't find ") + xml_desc; + } + return gCountString[ count_string_t(xml_desc, count) ]; +} + +std::string LLUI::getLanguage() +{ + return "en"; +} + +namespace tut +{ + struct dateutil + { + // Hard-code a "now" date so unit test doesn't change with + // current time. Because server strings are in Pacific time + // roll this forward 8 hours to compensate. This represents + // 2009-12-31T00:00:00Z UTC. + dateutil() + : mNow(std::string("2009-12-31T08:00:00Z")) + { + // copied from strings.xml + gString["YearsMonthsOld"] = "[AGEYEARS] [AGEMONTHS] old"; + gString["YearsOld"] = "[AGEYEARS] old"; + gString["MonthsOld"] = "[AGEMONTHS] old"; + gString["WeeksOld"] = "[AGEWEEKS] old"; + gString["DaysOld"] = "[AGEDAYS] old"; + gString["TodayOld"] = "Joined today"; + + gCountString[ count_string_t("AgeYears", 1) ] = "1 year"; + gCountString[ count_string_t("AgeYears", 2) ] = "2 years"; + gCountString[ count_string_t("AgeMonths", 1) ] = "1 month"; + gCountString[ count_string_t("AgeMonths", 2) ] = "2 months"; + gCountString[ count_string_t("AgeMonths", 11) ]= "11 months"; + gCountString[ count_string_t("AgeWeeks", 1) ] = "1 week"; + gCountString[ count_string_t("AgeWeeks", 2) ] = "2 weeks"; + gCountString[ count_string_t("AgeWeeks", 3) ] = "3 weeks"; + gCountString[ count_string_t("AgeWeeks", 4) ] = "4 weeks"; + gCountString[ count_string_t("AgeDays", 1) ] = "1 day"; + gCountString[ count_string_t("AgeDays", 2) ] = "2 days"; + } + LLDate mNow; + }; + + typedef test_group<dateutil> dateutil_t; + typedef dateutil_t::object dateutil_object_t; + tut::dateutil_t tut_dateutil("LLDateUtil"); + + template<> template<> + void dateutil_object_t::test<1>() + { + set_test_name("Years"); + ensure_equals("years + months", + LLDateUtil::ageFromDate("10/30/2007", mNow), + "2 years 2 months old" ); + ensure_equals("years", + LLDateUtil::ageFromDate("12/31/2007", mNow), + "2 years old" ); + ensure_equals("years", + LLDateUtil::ageFromDate("1/1/2008", mNow), + "1 year 11 months old" ); + ensure_equals("single year + one month", + LLDateUtil::ageFromDate("11/30/2008", mNow), + "1 year 1 month old" ); + ensure_equals("single year + a bit", + LLDateUtil::ageFromDate("12/12/2008", mNow), + "1 year old" ); + ensure_equals("single year", + LLDateUtil::ageFromDate("12/31/2008", mNow), + "1 year old" ); + } + + template<> template<> + void dateutil_object_t::test<2>() + { + set_test_name("Months"); + ensure_equals("months", + LLDateUtil::ageFromDate("10/30/2009", mNow), + "2 months old" ); + ensure_equals("months 2", + LLDateUtil::ageFromDate("10/31/2009", mNow), + "2 months old" ); + ensure_equals("single month", + LLDateUtil::ageFromDate("11/30/2009", mNow), + "1 month old" ); + } + + template<> template<> + void dateutil_object_t::test<3>() + { + set_test_name("Weeks"); + ensure_equals("4 weeks", + LLDateUtil::ageFromDate("12/1/2009", mNow), + "4 weeks old" ); + ensure_equals("weeks", + LLDateUtil::ageFromDate("12/17/2009", mNow), + "2 weeks old" ); + ensure_equals("single week", + LLDateUtil::ageFromDate("12/24/2009", mNow), + "1 week old" ); + } + + template<> template<> + void dateutil_object_t::test<4>() + { + set_test_name("Days"); + ensure_equals("days", + LLDateUtil::ageFromDate("12/29/2009", mNow), + "2 days old" ); + ensure_equals("single day", + LLDateUtil::ageFromDate("12/30/2009", mNow), + "1 day old" ); + ensure_equals("today", + LLDateUtil::ageFromDate("12/31/2009", mNow), + "Joined today" ); + } + + template<> template<> + void dateutil_object_t::test<5>() + { + set_test_name("2010 rollover"); + LLDate now(std::string("2010-01-04T12:00:00Z")); + ensure_equals("days", + LLDateUtil::ageFromDate("12/13/2009", now), + "3 weeks old" ); + } + + //template<> template<> + //void dateutil_object_t::test<6>() + //{ + // set_test_name("ISO dates"); + // LLDate now(std::string("2010-01-04T12:00:00Z")); + // ensure_equals("days", + // LLDateUtil::ageFromDateISO("2009-12-13", now), + // "3 weeks old" ); + //} +} diff --git a/indra/newview/tests/lllogininstance_test.cpp b/indra/newview/tests/lllogininstance_test.cpp new file mode 100644 index 0000000000..9e321db889 --- /dev/null +++ b/indra/newview/tests/lllogininstance_test.cpp @@ -0,0 +1,587 @@ +/** + * @file lllogininstance_test.cpp + * @brief Test for lllogininstance.cpp. + * + * $LicenseInfo:firstyear=2008&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +// Precompiled header +#include "../llviewerprecompiledheaders.h" +// Own header +#include "../llsecapi.h" +#include "../llviewernetwork.h" +#include "../lllogininstance.h" + +// STL headers +// std headers +// external library headers +// other Linden headers +#include "../test/lltut.h" +#include "llevents.h" + +#if defined(LL_WINDOWS) +#pragma warning(disable: 4355) // using 'this' in base-class ctor initializer expr +#pragma warning(disable: 4702) // disable 'unreachable code' so we can safely use skip(). +#endif + +// Constants +const std::string VIEWERLOGIN_URI("viewerlogin_uri"); +const std::string VIEWERLOGIN_GRIDLABEL("viewerlogin_grid"); + +const std::string APPVIEWER_SERIALNUMBER("appviewer_serialno"); + +const std::string VIEWERLOGIN_CHANNEL("invalid_channel"); +const std::string VIEWERLOGIN_VERSION_CHANNEL("invalid_version"); + +// Link seams. + +//----------------------------------------------------------------------------- +static LLEventStream gTestPump("test_pump"); + +#include "../llslurl.h" +#include "../llstartup.h" +LLSLURL LLStartUp::sStartSLURL; + +#include "lllogin.h" + +static std::string gLoginURI; +static LLSD gLoginCreds; +static bool gDisconnectCalled = false; + +#include "../llviewerwindow.h" +void LLViewerWindow::setShowProgress(BOOL show) {} +LLProgressView * LLViewerWindow::getProgressView(void) const { return 0; } + +LLViewerWindow* gViewerWindow; + +class LLLogin::Impl +{ +}; +LLLogin::LLLogin() {} +LLLogin::~LLLogin() {} +LLEventPump& LLLogin::getEventPump() { return gTestPump; } +void LLLogin::connect(const std::string& uri, const LLSD& credentials) +{ + gLoginURI = uri; + gLoginCreds = credentials; +} + +void LLLogin::disconnect() +{ + gDisconnectCalled = true; +} + +LLSD LLCredential::getLoginParams() +{ + LLSD result = LLSD::emptyMap(); + + // legacy credential + result["passwd"] = "$1$testpasssd"; + result["first"] = "myfirst"; + result["last"] ="mylast"; + return result; +} +void LLCredential::identifierType(std::string &idType) +{ +} + +void LLCredential::authenticatorType(std::string &idType) +{ +} + +//----------------------------------------------------------------------------- +#include "../llviewernetwork.h" +LLGridManager::~LLGridManager() +{ +} + +void LLGridManager::addGrid(LLSD& grid_data) +{ +} +LLGridManager::LLGridManager() +: + mIsInProductionGrid(false) +{ +} + +void LLGridManager::getLoginURIs(std::vector<std::string>& uris) +{ + uris.push_back(VIEWERLOGIN_URI); +} + +void LLGridManager::addSystemGrid(const std::string& label, + const std::string& name, + const std::string& login, + const std::string& helper, + const std::string& login_page, + const std::string& login_id) +{ +} +std::map<std::string, std::string> LLGridManager::getKnownGrids(bool favorite_only) +{ + std::map<std::string, std::string> result; + return result; +} + +void LLGridManager::setGridChoice(const std::string& grid_name) +{ +} + +bool LLGridManager::isInProductionGrid() +{ + return false; +} + +void LLGridManager::saveFavorites() +{} +std::string LLGridManager::getSLURLBase(const std::string& grid_name) +{ + return "myslurl"; +} +std::string LLGridManager::getAppSLURLBase(const std::string& grid_name) +{ + return "myappslurl"; +} + +//----------------------------------------------------------------------------- +#include "../llviewercontrol.h" +LLControlGroup gSavedSettings("Global"); + +LLControlGroup::LLControlGroup(const std::string& name) : + LLInstanceTracker<LLControlGroup, std::string>(name){} +LLControlGroup::~LLControlGroup() {} +void LLControlGroup::setBOOL(const std::string& name, BOOL val) {} +BOOL LLControlGroup::getBOOL(const std::string& name) { return FALSE; } +F32 LLControlGroup::getF32(const std::string& name) { return 0.0f; } +U32 LLControlGroup::saveToFile(const std::string& filename, BOOL nondefault_only) { return 1; } +void LLControlGroup::setString(const std::string& name, const std::string& val) {} +std::string LLControlGroup::getString(const std::string& name) { return "test_string"; } +BOOL LLControlGroup::declareBOOL(const std::string& name, BOOL initial_val, const std::string& comment, BOOL persist) { return TRUE; } +BOOL LLControlGroup::declareString(const std::string& name, const std::string &initial_val, const std::string& comment, BOOL persist) { return TRUE; } + +#include "lluicolortable.h" +void LLUIColorTable::saveUserSettings(void)const {} + +//----------------------------------------------------------------------------- +#include "../llversioninfo.h" +const std::string &LLVersionInfo::getChannelAndVersion() { return VIEWERLOGIN_VERSION_CHANNEL; } +const std::string &LLVersionInfo::getChannel() { return VIEWERLOGIN_CHANNEL; } + +//----------------------------------------------------------------------------- +#include "../llappviewer.h" +void LLAppViewer::forceQuit(void) {} +LLAppViewer * LLAppViewer::sInstance = 0; + +//----------------------------------------------------------------------------- +#include "llnotificationsutil.h" +LLNotificationPtr LLNotificationsUtil::add(const std::string& name, + const LLSD& substitutions, + const LLSD& payload, + boost::function<void (const LLSD&, const LLSD&)> functor) { return LLNotificationPtr((LLNotification*)0); } + + +//----------------------------------------------------------------------------- +#include "llupdaterservice.h" + +std::string const & LLUpdaterService::pumpName(void) +{ + static std::string wakka = "wakka wakka wakka"; + return wakka; +} +bool LLUpdaterService::updateReadyToInstall(void) { return false; } +void LLUpdaterService::initialize(const std::string& protocol_version, + const std::string& url, + const std::string& path, + const std::string& channel, + const std::string& version) {} + +void LLUpdaterService::setCheckPeriod(unsigned int seconds) {} +void LLUpdaterService::startChecking(bool install_if_ready) {} +void LLUpdaterService::stopChecking() {} +bool LLUpdaterService::isChecking() { return false; } +LLUpdaterService::eUpdaterState LLUpdaterService::getState() { return INITIAL; } +std::string LLUpdaterService::updatedVersion() { return ""; } + +//----------------------------------------------------------------------------- +#include "llnotifications.h" +#include "llfloaterreg.h" +static std::string gTOSType; +static LLEventPump * gTOSReplyPump = NULL; + +//static +LLFloater* LLFloaterReg::showInstance(const std::string& name, const LLSD& key, BOOL focus) +{ + gTOSType = name; + gTOSReplyPump = &LLEventPumps::instance().obtain(key["reply_pump"]); + return NULL; +} + +//---------------------------------------------------------------------------- +#include "../llprogressview.h" +void LLProgressView::setText(std::string const &){} +void LLProgressView::setPercent(float){} +void LLProgressView::setMessage(std::string const &){} + +//----------------------------------------------------------------------------- +// LLNotifications +class MockNotifications : public LLNotificationsInterface +{ + boost::function<void (const LLSD&, const LLSD&)> mResponder; + int mAddedCount; + +public: + MockNotifications() : + mResponder(0), + mAddedCount(0) + { + } + + virtual ~MockNotifications() {} + + /* virtual */ LLNotificationPtr add( + const std::string& name, + const LLSD& substitutions, + const LLSD& payload, + LLNotificationFunctorRegistry::ResponseFunctor functor) + { + mResponder = functor; + mAddedCount++; + return LLNotificationPtr((LLNotification*)NULL); + } + + void sendYesResponse() + { + LLSD notification; + LLSD response; + response = 1; + mResponder(notification, response); + } + + void sendNoResponse() + { + LLSD notification; + LLSD response; + response = 2; + mResponder(notification, response); + } + + void sendBogusResponse() + { + LLSD notification; + LLSD response; + response = 666; + mResponder(notification, response); + } + + int addedCount() { return mAddedCount; } +}; + +S32 LLNotification::getSelectedOption(const LLSD& notification, const LLSD& response) +{ + return response.asInteger(); +} + +//----------------------------------------------------------------------------- +#include "../llmachineid.h" +unsigned char gMACAddress[MAC_ADDRESS_BYTES] = {77,21,46,31,89,2}; + +S32 LLMachineID::getUniqueID(unsigned char *unique_id, size_t len) +{ + memcpy(unique_id, gMACAddress, len); + return 1; +} +//----------------------------------------------------------------------------- +// misc +std::string xml_escape_string(const std::string& in) +{ + return in; +} + +/***************************************************************************** +* TUT +*****************************************************************************/ +namespace tut +{ + struct lllogininstance_data + { + lllogininstance_data() : logininstance(LLLoginInstance::getInstance()) + { + // Global initialization + gLoginURI.clear(); + gLoginCreds.clear(); + gDisconnectCalled = false; + + gTOSType = ""; // Set to invalid value. + gTOSReplyPump = 0; // clear the callback. + + + gSavedSettings.declareBOOL("NoInventoryLibrary", FALSE, "", FALSE); + gSavedSettings.declareBOOL("ConnectAsGod", FALSE, "", FALSE); + gSavedSettings.declareBOOL("UseDebugMenus", FALSE, "", FALSE); + gSavedSettings.declareBOOL("ForceMandatoryUpdate", FALSE, "", FALSE); + gSavedSettings.declareString("ClientSettingsFile", "test_settings.xml", "", FALSE); + gSavedSettings.declareString("NextLoginLocation", "", "", FALSE); + gSavedSettings.declareBOOL("LoginLastLocation", FALSE, "", FALSE); + + LLSD authenticator = LLSD::emptyMap(); + LLSD identifier = LLSD::emptyMap(); + identifier["type"] = "agent"; + identifier["first_name"] = "testfirst"; + identifier["last_name"] = "testlast"; + authenticator["passwd"] = "testpass"; + agentCredential = new LLCredential(); + agentCredential->setCredentialData(identifier, authenticator); + + authenticator = LLSD::emptyMap(); + identifier = LLSD::emptyMap(); + identifier["type"] = "account"; + identifier["username"] = "testuser"; + authenticator["secret"] = "testsecret"; + accountCredential = new LLCredential(); + accountCredential->setCredentialData(identifier, authenticator); + + logininstance->setNotificationsInterface(¬ifications); + } + + LLLoginInstance* logininstance; + LLPointer<LLCredential> agentCredential; + LLPointer<LLCredential> accountCredential; + MockNotifications notifications; + }; + + typedef test_group<lllogininstance_data> lllogininstance_group; + typedef lllogininstance_group::object lllogininstance_object; + lllogininstance_group llsdmgr("LLLoginInstance"); + + template<> template<> + void lllogininstance_object::test<1>() + { + set_test_name("Test Simple Success And Disconnect"); + + // Test default connect. + logininstance->connect(agentCredential); + + ensure_equals("Default connect uri", gLoginURI, VIEWERLOGIN_URI); + + // Dummy success response. + LLSD response; + response["state"] = "online"; + response["change"] = "connect"; + response["progress"] = 1.0; + response["transfer_rate"] = 7; + response["data"] = "test_data"; + + gTestPump.post(response); + + ensure("Success response", logininstance->authSuccess()); + ensure_equals("Test Response Data", logininstance->getResponse().asString(), "test_data"); + + logininstance->disconnect(); + + ensure_equals("Called Login Module Disconnect", gDisconnectCalled, true); + + response.clear(); + response["state"] = "offline"; + response["change"] = "disconnect"; + response["progress"] = 0.0; + response["transfer_rate"] = 0; + response["data"] = "test_data"; + + gTestPump.post(response); + + ensure("Disconnected", !(logininstance->authSuccess())); + } + + template<> template<> + void lllogininstance_object::test<2>() + { + set_test_name("Test User TOS/Critical message Interaction"); + + const std::string test_uri = "testing-uri"; + + // Test default connect. + logininstance->connect(test_uri, agentCredential); + + // connect should call LLLogin::connect to init gLoginURI and gLoginCreds. + ensure_equals("Default connect uri", gLoginURI, "testing-uri"); + ensure_equals("Default for agree to tos", gLoginCreds["params"]["agree_to_tos"].asBoolean(), false); + ensure_equals("Default for read critical", gLoginCreds["params"]["read_critical"].asBoolean(), false); + + // TOS failure response. + LLSD response; + response["state"] = "offline"; + response["change"] = "fail.login"; + response["progress"] = 0.0; + response["transfer_rate"] = 7; + response["data"]["reason"] = "tos"; + gTestPump.post(response); + + ensure_equals("TOS Dialog type", gTOSType, "message_tos"); + ensure("TOS callback given", gTOSReplyPump != 0); + gTOSReplyPump->post(false); // Call callback denying TOS. + ensure("No TOS, failed auth", logininstance->authFailure()); + + // Start again. + logininstance->connect(test_uri, agentCredential); + gTestPump.post(response); // Fail for tos again. + gTOSReplyPump->post(true); // Accept tos, should reconnect w/ agree_to_tos. + ensure_equals("Accepted agree to tos", gLoginCreds["params"]["agree_to_tos"].asBoolean(), true); + ensure("Incomplete login status", !logininstance->authFailure() && !logininstance->authSuccess()); + + // Fail connection, attempt connect again. + // The new request should have reset agree to tos to default. + response["data"]["reason"] = "key"; // bad creds. + gTestPump.post(response); + ensure("TOS auth failure", logininstance->authFailure()); + + logininstance->connect(test_uri, agentCredential); + ensure_equals("Reset to default for agree to tos", gLoginCreds["params"]["agree_to_tos"].asBoolean(), false); + + // Critical Message failure response. + logininstance->connect(test_uri, agentCredential); + response["data"]["reason"] = "critical"; // Change response to "critical message" + gTestPump.post(response); + + ensure_equals("TOS Dialog type", gTOSType, "message_critical"); + ensure("TOS callback given", gTOSReplyPump != 0); + gTOSReplyPump->post(true); + ensure_equals("Accepted read critical message", gLoginCreds["params"]["read_critical"].asBoolean(), true); + ensure("Incomplete login status", !logininstance->authFailure() && !logininstance->authSuccess()); + + // Fail then attempt new connection + response["data"]["reason"] = "key"; // bad creds. + gTestPump.post(response); + ensure("TOS auth failure", logininstance->authFailure()); + logininstance->connect(test_uri, agentCredential); + ensure_equals("Default for agree to tos", gLoginCreds["params"]["read_critical"].asBoolean(), false); + } + + template<> template<> + void lllogininstance_object::test<3>() + { + skip(); + + set_test_name("Test Mandatory Update User Accepts"); + + // Part 1 - Mandatory Update, with User accepts response. + // Test connect with update needed. + logininstance->connect(agentCredential); + + ensure_equals("Default connect uri", gLoginURI, VIEWERLOGIN_URI); + + // Update needed failure response. + LLSD response; + response["state"] = "offline"; + response["change"] = "fail.login"; + response["progress"] = 0.0; + response["transfer_rate"] = 7; + response["data"]["reason"] = "update"; + gTestPump.post(response); + + ensure_equals("Notification added", notifications.addedCount(), 1); + + notifications.sendYesResponse(); + + ensure("Disconnected", !(logininstance->authSuccess())); + } + + template<> template<> + void lllogininstance_object::test<4>() + { + skip(); + + set_test_name("Test Mandatory Update User Decline"); + + // Test connect with update needed. + logininstance->connect(agentCredential); + + ensure_equals("Default connect uri", gLoginURI, VIEWERLOGIN_URI); + + // Update needed failure response. + LLSD response; + response["state"] = "offline"; + response["change"] = "fail.login"; + response["progress"] = 0.0; + response["transfer_rate"] = 7; + response["data"]["reason"] = "update"; + gTestPump.post(response); + + ensure_equals("Notification added", notifications.addedCount(), 1); + notifications.sendNoResponse(); + + ensure("Disconnected", !(logininstance->authSuccess())); + } + + template<> template<> + void lllogininstance_object::test<6>() + { + set_test_name("Test Optional Update User Accept"); + + // Part 3 - Mandatory Update, with bogus response. + // Test connect with update needed. + logininstance->connect(agentCredential); + + ensure_equals("Default connect uri", gLoginURI, VIEWERLOGIN_URI); + + // Update needed failure response. + LLSD response; + response["state"] = "offline"; + response["change"] = "fail.login"; + response["progress"] = 0.0; + response["transfer_rate"] = 7; + response["data"]["reason"] = "optional"; + gTestPump.post(response); + + ensure_equals("Notification added", notifications.addedCount(), 1); + notifications.sendYesResponse(); + + ensure("Disconnected", !(logininstance->authSuccess())); + } + + template<> template<> + void lllogininstance_object::test<7>() + { + set_test_name("Test Optional Update User Denies"); + + // Part 3 - Mandatory Update, with bogus response. + // Test connect with update needed. + logininstance->connect(agentCredential); + + ensure_equals("Default connect uri", gLoginURI, VIEWERLOGIN_URI); + + // Update needed failure response. + LLSD response; + response["state"] = "offline"; + response["change"] = "fail.login"; + response["progress"] = 0.0; + response["transfer_rate"] = 7; + response["data"]["reason"] = "optional"; + gTestPump.post(response); + + ensure_equals("Notification added", notifications.addedCount(), 1); + notifications.sendNoResponse(); + + // User skips, should be reconnecting. + ensure_equals("reconnect uri", gLoginURI, VIEWERLOGIN_URI); + ensure_equals("skipping optional update", gLoginCreds["params"]["skipoptional"].asBoolean(), true); + } +} diff --git a/indra/newview/tests/llmediadataclient_test.cpp b/indra/newview/tests/llmediadataclient_test.cpp new file mode 100644 index 0000000000..0254c5881f --- /dev/null +++ b/indra/newview/tests/llmediadataclient_test.cpp @@ -0,0 +1,969 @@ +/** + * @file llmediadataclient_test.cpp + * @brief LLMediaDatClient tests + * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "linden_common.h" +#include "../llviewerprecompiledheaders.h" + +#include <iostream> +#include "../test/lltut.h" + +#include "llsdserialize.h" +#include "llsdutil.h" +#include "llerrorcontrol.h" +#include "llhttpstatuscodes.h" + +#include "../llmediadataclient.h" +#include "../llvovolume.h" + +#include "../../llprimitive/llmediaentry.cpp" +#include "../../llprimitive/lltextureentry.cpp" +#include "../../llmessage/tests/llcurl_stub.cpp" + +#if LL_WINDOWS +#pragma warning (push) +#pragma warning (disable : 4702) // boost::lexical_cast generates this warning +#endif +#include <boost/lexical_cast.hpp> +#if LL_WINDOWS +#pragma warning (pop) +#endif + +#define VALID_OBJECT_ID "3607d5c4-644b-4a8a-871a-8b78471af2a2" +#define VALID_OBJECT_ID_1 "11111111-1111-1111-1111-111111111111" +#define VALID_OBJECT_ID_2 "22222222-2222-2222-2222-222222222222" +#define VALID_OBJECT_ID_3 "33333333-3333-3333-3333-333333333333" +#define VALID_OBJECT_ID_4 "44444444-4444-4444-4444-444444444444" + +#define FAKE_OBJECT_MEDIA_CAP_URL "foo_ObjectMedia" +#define FAKE_OBJECT_MEDIA_NAVIGATE_CAP_URL "foo_ObjectMediaNavigate" +#define FAKE_OBJECT_MEDIA_CAP_URL_503 "foo_ObjectMedia_503" +#define FAKE_OBJECT_MEDIA_NAVIGATE_CAP_URL_ERROR "foo_ObjectMediaNavigate_ERROR" + +#define MEDIA_DATA "\ +<array> \ +<string>http://foo.example.com</string> \ +<string>http://bar.example.com</string> \ +<string>baz</string> \ +</array>" + +#define _DATA_URLS(ID,INTEREST,NEW,URL1,URL2) " \ +<llsd> \ + <map> \ + <key>uuid</key> \ + <string>" ID "</string> \ + <key>interest</key> \ + <real>" INTEREST "</real> \ + <key>cap_urls</key> \ + <map> \ + <key>ObjectMedia</key> \ + <string>" URL1 "</string> \ + <key>ObjectMediaNavigate</key> \ + <string>" URL2 "</string> \ + </map> \ + <key>media_data</key> \ + " MEDIA_DATA " \ + <key>is_dead</key> \ + <boolean>false</boolean> \ + <key>is_new</key> \ + <boolean>" NEW "</boolean> \ + </map> \ +</llsd>" + +#define _DATA(ID,INTEREST,NEW) _DATA_URLS(ID,INTEREST,NEW,FAKE_OBJECT_MEDIA_CAP_URL,FAKE_OBJECT_MEDIA_NAVIGATE_CAP_URL) + +const char *DATA = _DATA(VALID_OBJECT_ID,"1.0","true"); + +#define STR(I) boost::lexical_cast<std::string>(I) + +#define LOG_TEST(N) LL_DEBUGS("LLMediaDataClient") << "\n" << \ +"================================================================================\n" << \ +"==================================== TEST " #N " ===================================\n" << \ +"================================================================================\n" << LL_ENDL; + +LLSD *gPostRecords = NULL; +F64 gMinimumInterestLevel = (F64)0.0; + +// stubs: +void LLHTTPClient::post( + const std::string& url, + const LLSD& body, + LLHTTPClient::ResponderPtr responder, + const LLSD& headers, + const F32 timeout) +{ + LLSD record; + record["url"] = url; + record["body"] = body; + record["headers"] = headers; + record["timeout"] = timeout; + gPostRecords->append(record); + + // Magic URL that triggers a 503: + LLSD result; + result[LLTextureEntry::OBJECT_ID_KEY] = body[LLTextureEntry::OBJECT_ID_KEY]; + if ( url == FAKE_OBJECT_MEDIA_CAP_URL_503 ) + { + responder->error(HTTP_SERVICE_UNAVAILABLE, "fake reason"); + return; + } + else if (url == FAKE_OBJECT_MEDIA_NAVIGATE_CAP_URL_ERROR) + { + LLSD error; + error["code"] = LLObjectMediaNavigateClient::ERROR_PERMISSION_DENIED_CODE; + result["error"] = error; + } + responder->result(result); +} + +const F32 HTTP_REQUEST_EXPIRY_SECS = 60.0f; + +class LLMediaDataClientObjectTest : public LLMediaDataClientObject +{ +public: + LLMediaDataClientObjectTest(const char *data) + { + std::istringstream d(data); + LLSDSerialize::fromXML(mRep, d); + mNumBounceBacks = 0; + + // std::cout << ll_pretty_print_sd(mRep) << std::endl; + // std::cout << "ID: " << getID() << std::endl; + } + LLMediaDataClientObjectTest(const LLSD &rep) + : mRep(rep), mNumBounceBacks(0) {} + ~LLMediaDataClientObjectTest() + { LL_DEBUGS("LLMediaDataClient") << "~LLMediaDataClientObjectTest" << LL_ENDL; } + + virtual U8 getMediaDataCount() const + { return mRep["media_data"].size(); } + virtual LLSD getMediaDataLLSD(U8 index) const + { return mRep["media_data"][(LLSD::Integer)index]; } + virtual bool isCurrentMediaUrl(U8 index, const std::string &url) const + { return (mRep["media_data"][(LLSD::Integer)index].asString() == url); } + virtual LLUUID getID() const + { return mRep["uuid"]; } + virtual void mediaNavigateBounceBack(U8 index) + { mNumBounceBacks++; } + + virtual bool hasMedia() const + { return mRep.has("media_data"); } + + virtual void updateObjectMediaData(LLSD const &media_data_array, const std::string &media_version) + { mRep["media_data"] = media_data_array; mRep["media_version"] = media_version; } + + virtual F64 getMediaInterest() const + { return (LLSD::Real)mRep["interest"]; } + + virtual bool isInterestingEnough() const + { return getMediaInterest() > gMinimumInterestLevel; } + + virtual std::string getCapabilityUrl(const std::string &name) const + { return mRep["cap_urls"][name]; } + + virtual bool isDead() const + { return mRep["is_dead"]; } + + virtual U32 getMediaVersion() const + { return (LLSD::Integer)mRep["media_version"]; } + + virtual bool isNew() const + { return mRep["is_new"]; } + + void setMediaInterest(F64 val) + { mRep["interest"] = val; } + + int getNumBounceBacks() const + { return mNumBounceBacks; } + + void markDead() + { mRep["is_dead"] = true; } + + void markOld() + { mRep["is_new"] = false; } + +private: + LLSD mRep; + int mNumBounceBacks; +}; + +// This special timer delay should ensure that the timer will fire on the very +// next pump, no matter what (though this does make an assumption about the +// implementation of LLEventTimer::updateClass()): +const F32 NO_PERIOD = -1000.0f; + +static void pump_timers() +{ + LLEventTimer::updateClass(); +} + +namespace tut +{ + struct mediadataclient + { + mediadataclient() { + gPostRecords = &mLLSD; + gMinimumInterestLevel = (F64)0.0; + +// LLError::setDefaultLevel(LLError::LEVEL_DEBUG); +// LLError::setClassLevel("LLMediaDataClient", LLError::LEVEL_DEBUG); +// LLError::setTagLevel("MediaOnAPrim", LLError::LEVEL_DEBUG); + } + LLSD mLLSD; + }; + + typedef test_group<mediadataclient> mediadataclient_t; + typedef mediadataclient_t::object mediadataclient_object_t; + tut::mediadataclient_t tut_mediadataclient("LLMediaDataClient"); + + void ensure(const std::string &msg, int value, int expected) + { + std::string m = msg; + m += " value: " + STR(value); + m += ", expected: " + STR(expected); + ensure(m, value == expected); + } + + void ensure(const std::string &msg, const std::string & value, const std::string & expected) + { + std::string m = msg; + m += " value: " + value; + m += ", expected: " + expected; + ensure(m, value == expected); + } + + void ensure(const std::string &msg, const LLUUID & value, const LLUUID & expected) + { + std::string m = msg; + m += " value: " + value.asString(); + m += ", expected: " + expected.asString(); + ensure(m, value == expected); + } + + void ensure_llsd(const std::string &msg, const LLSD & value, const char *expected) + { + LLSD expected_llsd; + std::istringstream e(expected); + LLSDSerialize::fromXML(expected_llsd, e); + + std::string value_str = ll_pretty_print_sd(value); + std::string expected_str = ll_pretty_print_sd(expected_llsd); + std::string m = msg; + m += " value: " + value_str; + m += ", expected: " + expected_str; + ensure(m, value_str == expected_str); + } + + ////////////////////////////////////////////////////////////////////////////////////////// + + template<> template<> + void mediadataclient_object_t::test<1>() + { + // + // Test fetchMedia() + // + LOG_TEST(1); + + LLMediaDataClientObject::ptr_t o = new LLMediaDataClientObjectTest(DATA); + int num_refs_start = o->getNumRefs(); + { + LLPointer<LLObjectMediaDataClient> mdc = new LLObjectMediaDataClient(NO_PERIOD,NO_PERIOD); + mdc->fetchMedia(o); + + // Make sure no posts happened yet... + ensure("post records", gPostRecords->size(), 0); + + ::pump_timers(); + + ensure("post records", gPostRecords->size(), 1); + ensure("post url", (*gPostRecords)[0]["url"], FAKE_OBJECT_MEDIA_CAP_URL); + ensure("post GET", (*gPostRecords)[0]["body"]["verb"], "GET"); + ensure("post object id", (*gPostRecords)[0]["body"][LLTextureEntry::OBJECT_ID_KEY].asUUID(), LLUUID(VALID_OBJECT_ID)); + ensure("queue empty", mdc->isEmpty()); + } + + // Make sure everyone's destroyed properly + ensure("REF COUNT", o->getNumRefs(), num_refs_start); + } + + ////////////////////////////////////////////////////////////////////////////////////////// + + template<> template<> + void mediadataclient_object_t::test<2>() + { + // + // Test updateMedia() + // + LOG_TEST(2); + + LLMediaDataClientObject::ptr_t o = new LLMediaDataClientObjectTest(DATA); + { + // queue time w/ no delay ensures that ::pump_timers() will hit the tick() + LLPointer<LLObjectMediaDataClient> mdc = new LLObjectMediaDataClient(NO_PERIOD,NO_PERIOD); + mdc->updateMedia(o); + ensure("post records", gPostRecords->size(), 0); + ::pump_timers(); + + ensure("post records", gPostRecords->size(), 1); + ensure("post url", (*gPostRecords)[0]["url"], FAKE_OBJECT_MEDIA_CAP_URL); + ensure("post UPDATE", (*gPostRecords)[0]["body"]["verb"], "UPDATE"); + ensure("post object id", (*gPostRecords)[0]["body"][LLTextureEntry::OBJECT_ID_KEY].asUUID(), LLUUID(VALID_OBJECT_ID)); + ensure_llsd("post data llsd", (*gPostRecords)[0]["body"][LLTextureEntry::OBJECT_MEDIA_DATA_KEY], + "<llsd>" MEDIA_DATA "</llsd>"); + ensure("queue empty", mdc->isEmpty()); + } + + ensure("REF COUNT", o->getNumRefs(), 1); + } + + ////////////////////////////////////////////////////////////////////////////////////////// + + template<> template<> + void mediadataclient_object_t::test<3>() + { + // + // Test navigate() + // + LOG_TEST(3); + + LLMediaDataClientObject::ptr_t o = new LLMediaDataClientObjectTest(DATA); + { + LLPointer<LLObjectMediaNavigateClient> mdc = new LLObjectMediaNavigateClient(NO_PERIOD,NO_PERIOD); + const char *TEST_URL = "http://example.com"; + mdc->navigate(o, 0, TEST_URL); + ensure("post records", gPostRecords->size(), 0); + ::pump_timers(); + + // ensure no bounce back + ensure("bounce back", dynamic_cast<LLMediaDataClientObjectTest*>(static_cast<LLMediaDataClientObject*>(o))->getNumBounceBacks(), 0); + + ensure("post records", gPostRecords->size(), 1); + ensure("post url", (*gPostRecords)[0]["url"], FAKE_OBJECT_MEDIA_NAVIGATE_CAP_URL); + ensure("post object id", (*gPostRecords)[0]["body"][LLTextureEntry::OBJECT_ID_KEY].asUUID(), LLUUID(VALID_OBJECT_ID)); + ensure("post data", (*gPostRecords)[0]["body"][LLTextureEntry::TEXTURE_INDEX_KEY], 0); + ensure("post data", (*gPostRecords)[0]["body"][LLMediaEntry::CURRENT_URL_KEY], TEST_URL); + ensure("queue empty", mdc->isEmpty()); + } + ensure("REF COUNT", o->getNumRefs(), 1); + } + + ////////////////////////////////////////////////////////////////////////////////////////// + + template<> template<> + void mediadataclient_object_t::test<4>() + { + // + // Test queue ordering + // + LOG_TEST(4); + + LLMediaDataClientObject::ptr_t o1 = new LLMediaDataClientObjectTest( + _DATA(VALID_OBJECT_ID_1,"1.0","true")); + LLMediaDataClientObject::ptr_t o2 = new LLMediaDataClientObjectTest( + _DATA(VALID_OBJECT_ID_2,"3.0","true")); + LLMediaDataClientObject::ptr_t o3 = new LLMediaDataClientObjectTest( + _DATA(VALID_OBJECT_ID_3,"2.0","true")); + { + LLPointer<LLObjectMediaDataClient> mdc = new LLObjectMediaDataClient(NO_PERIOD,NO_PERIOD); + const char *ORDERED_OBJECT_IDS[] = { VALID_OBJECT_ID_2, VALID_OBJECT_ID_3, VALID_OBJECT_ID_1 }; + mdc->fetchMedia(o1); + mdc->fetchMedia(o2); + mdc->fetchMedia(o3); + + // Make sure no posts happened yet... + ensure("post records", gPostRecords->size(), 0); + + // tick 3 times... + ::pump_timers(); + ensure("post records", gPostRecords->size(), 1); + ::pump_timers(); + ensure("post records", gPostRecords->size(), 2); + ::pump_timers(); + ensure("post records", gPostRecords->size(), 3); + + for( int i=0; i < 3; i++ ) + { + ensure("[" + STR(i) + "] post url", (*gPostRecords)[i]["url"], FAKE_OBJECT_MEDIA_CAP_URL); + ensure("[" + STR(i) + "] post GET", (*gPostRecords)[i]["body"]["verb"], "GET"); + ensure("[" + STR(i) + "] post object id", (*gPostRecords)[i]["body"][LLTextureEntry::OBJECT_ID_KEY].asUUID(), + LLUUID(ORDERED_OBJECT_IDS[i])); + } + + ensure("queue empty", mdc->isEmpty()); + } + ensure("refcount of o1", o1->getNumRefs(), 1); + ensure("refcount of o2", o2->getNumRefs(), 1); + ensure("refcount of o3", o3->getNumRefs(), 1); + } + + ////////////////////////////////////////////////////////////////////////////////////////// + + template<> template<> + void mediadataclient_object_t::test<5>() + { + // + // Test fetchMedia() getting a 503 error + // + LOG_TEST(5); + + LLMediaDataClientObject::ptr_t o = new LLMediaDataClientObjectTest( + _DATA_URLS(VALID_OBJECT_ID, + "1.0","true", + FAKE_OBJECT_MEDIA_CAP_URL_503, + FAKE_OBJECT_MEDIA_NAVIGATE_CAP_URL)); + int num_refs_start = o->getNumRefs(); + { + const int NUM_RETRIES = 5; + LLPointer<LLObjectMediaDataClient> mdc = new LLObjectMediaDataClient(NO_PERIOD,NO_PERIOD,NUM_RETRIES); + + // This should generate a retry + mdc->fetchMedia(o); + + // Make sure no posts happened yet... + ensure("post records before", gPostRecords->size(), 0); + + // Once, causes retry + // Second, fires retry timer + // Third, fires queue timer again + for (int i=0; i<NUM_RETRIES; ++i) + { + ::pump_timers(); // Should pump (fire) the queue timer, causing a retry timer to be scheduled + // XXX This ensure is not guaranteed, because scheduling a timer might actually get it pumped in the same loop + //ensure("post records " + STR(i), gPostRecords->size(), i+1); + ::pump_timers(); // Should pump (fire) the retry timer, scheduling the queue timer + } + + // Do some extra pumps to make sure no other timer work occurs. + ::pump_timers(); + ::pump_timers(); + ::pump_timers(); + + // Make sure there were 2 posts + ensure("post records after", gPostRecords->size(), NUM_RETRIES); + for (int i=0; i<NUM_RETRIES; ++i) + { + ensure("[" + STR(i) + "] post url", (*gPostRecords)[i]["url"], FAKE_OBJECT_MEDIA_CAP_URL_503); + ensure("[" + STR(i) + "] post GET", (*gPostRecords)[i]["body"]["verb"], "GET"); + ensure("[" + STR(i) + "] post object id", (*gPostRecords)[i]["body"][LLTextureEntry::OBJECT_ID_KEY].asUUID(), LLUUID(VALID_OBJECT_ID)); + } + ensure("queue empty", mdc->isEmpty()); + } + + // Make sure everyone's destroyed properly + ensure("REF COUNT", o->getNumRefs(), num_refs_start); + } + + template<> template<> + void mediadataclient_object_t::test<6>() + { + // + // Test navigate() with a bounce back + // + LOG_TEST(6); + + LLMediaDataClientObject::ptr_t o = new LLMediaDataClientObjectTest( + _DATA_URLS(VALID_OBJECT_ID, + "1.0","true", + FAKE_OBJECT_MEDIA_CAP_URL, + FAKE_OBJECT_MEDIA_NAVIGATE_CAP_URL_ERROR)); + { + LLPointer<LLObjectMediaNavigateClient> mdc = new LLObjectMediaNavigateClient(NO_PERIOD,NO_PERIOD); + const char *TEST_URL = "http://example.com"; + mdc->navigate(o, 0, TEST_URL); + ensure("post records", gPostRecords->size(), 0); + ::pump_timers(); + + // ensure bounce back + ensure("bounce back", + dynamic_cast<LLMediaDataClientObjectTest*>(static_cast<LLMediaDataClientObject*>(o))->getNumBounceBacks(), + 1); + + ensure("post records", gPostRecords->size(), 1); + ensure("post url", (*gPostRecords)[0]["url"], FAKE_OBJECT_MEDIA_NAVIGATE_CAP_URL_ERROR); + ensure("post object id", (*gPostRecords)[0]["body"][LLTextureEntry::OBJECT_ID_KEY].asUUID(), LLUUID(VALID_OBJECT_ID)); + ensure("post data", (*gPostRecords)[0]["body"][LLTextureEntry::TEXTURE_INDEX_KEY], 0); + ensure("post data", (*gPostRecords)[0]["body"][LLMediaEntry::CURRENT_URL_KEY], TEST_URL); + ensure("queue empty", mdc->isEmpty()); + } + ensure("REF COUNT", o->getNumRefs(), 1); + } + + template<> template<> + void mediadataclient_object_t::test<7>() + { + // Test LLMediaDataClient::isInQueue() + LOG_TEST(7); + + LLMediaDataClientObject::ptr_t o1 = new LLMediaDataClientObjectTest( + _DATA(VALID_OBJECT_ID_1,"3.0","true")); + LLMediaDataClientObject::ptr_t o2 = new LLMediaDataClientObjectTest( + _DATA(VALID_OBJECT_ID_2,"1.0","true")); + int num_refs_start = o1->getNumRefs(); + { + LLPointer<LLObjectMediaDataClient> mdc = new LLObjectMediaDataClient(NO_PERIOD,NO_PERIOD); + + ensure("not in queue yet 1", ! mdc->isInQueue(o1)); + ensure("not in queue yet 2", ! mdc->isInQueue(o2)); + + mdc->fetchMedia(o1); + + ensure("is in queue", mdc->isInQueue(o1)); + ensure("is not in queue", ! mdc->isInQueue(o2)); + + ::pump_timers(); + + ensure("not in queue anymore", ! mdc->isInQueue(o1)); + ensure("still is not in queue", ! mdc->isInQueue(o2)); + + ensure("queue empty", mdc->isEmpty()); + } + + // Make sure everyone's destroyed properly + ensure("REF COUNT", o1->getNumRefs(), num_refs_start); + + } + + template<> template<> + void mediadataclient_object_t::test<8>() + { + // Test queue handling of objects that are marked dead. + LOG_TEST(8); + + LLMediaDataClientObject::ptr_t o1 = new LLMediaDataClientObjectTest(_DATA(VALID_OBJECT_ID_1,"4.0","true")); + LLMediaDataClientObject::ptr_t o2 = new LLMediaDataClientObjectTest(_DATA(VALID_OBJECT_ID_2,"3.0","true")); + LLMediaDataClientObject::ptr_t o3 = new LLMediaDataClientObjectTest(_DATA(VALID_OBJECT_ID_3,"2.0","true")); + LLMediaDataClientObject::ptr_t o4 = new LLMediaDataClientObjectTest(_DATA(VALID_OBJECT_ID_4,"1.0","true")); + { + LLPointer<LLObjectMediaDataClient> mdc = new LLObjectMediaDataClient(NO_PERIOD,NO_PERIOD); + + // queue up all 4 objects + mdc->fetchMedia(o1); + mdc->fetchMedia(o2); + mdc->fetchMedia(o3); + mdc->fetchMedia(o4); + + ensure("is in queue 1", mdc->isInQueue(o1)); + ensure("is in queue 2", mdc->isInQueue(o2)); + ensure("is in queue 3", mdc->isInQueue(o3)); + ensure("is in queue 4", mdc->isInQueue(o4)); + ensure("post records", gPostRecords->size(), 0); + + // and mark the second and fourth ones dead. Call removeFromQueue when marking dead, since this is what LLVOVolume will do. + dynamic_cast<LLMediaDataClientObjectTest*>(static_cast<LLMediaDataClientObject*>(o2))->markDead(); + mdc->removeFromQueue(o2); + dynamic_cast<LLMediaDataClientObjectTest*>(static_cast<LLMediaDataClientObject*>(o4))->markDead(); + mdc->removeFromQueue(o4); + + // The removeFromQueue calls should remove the second and fourth ones + ensure("is in queue 1", mdc->isInQueue(o1)); + ensure("is not in queue 2", !mdc->isInQueue(o2)); + ensure("is in queue 3", mdc->isInQueue(o3)); + ensure("is not in queue 4", !mdc->isInQueue(o4)); + ensure("post records", gPostRecords->size(), 0); + + ::pump_timers(); + + // The first tick should process the first item + ensure("is not in queue 1", !mdc->isInQueue(o1)); + ensure("is not in queue 2", !mdc->isInQueue(o2)); + ensure("is in queue 3", mdc->isInQueue(o3)); + ensure("is not in queue 4", !mdc->isInQueue(o4)); + ensure("post records", gPostRecords->size(), 1); + + ::pump_timers(); + + // The second tick should process the third, emptying the queue + ensure("is not in queue 3", !mdc->isInQueue(o3)); + ensure("post records", gPostRecords->size(), 2); + + ensure("queue empty", mdc->isEmpty()); + } + ensure("refcount of o1", o1->getNumRefs(), 1); + ensure("refcount of o2", o2->getNumRefs(), 1); + ensure("refcount of o3", o3->getNumRefs(), 1); + ensure("refcount of o4", o4->getNumRefs(), 1); + + } + + ////////////////////////////////////////////////////////////////////////////////////////// + + template<> template<> + void mediadataclient_object_t::test<9>() + { + // + // Test queue re-ordering + // + LOG_TEST(9); + + LLMediaDataClientObject::ptr_t o1 = new LLMediaDataClientObjectTest(_DATA(VALID_OBJECT_ID_1,"40.0","true")); + LLMediaDataClientObject::ptr_t o2 = new LLMediaDataClientObjectTest(_DATA(VALID_OBJECT_ID_2,"30.0","true")); + LLMediaDataClientObject::ptr_t o3 = new LLMediaDataClientObjectTest(_DATA(VALID_OBJECT_ID_3,"20.0","true")); + LLMediaDataClientObjectTest *object4 = new LLMediaDataClientObjectTest(_DATA(VALID_OBJECT_ID_4,"10.0","true")); + LLMediaDataClientObject::ptr_t o4 = object4; + { + LLPointer<LLObjectMediaDataClient> mdc = new LLObjectMediaDataClient(NO_PERIOD,NO_PERIOD); + + // queue up all 4 objects. They should now be in the queue in + // order 1 through 4, with 4 being at the front of the queue + mdc->fetchMedia(o1); + mdc->fetchMedia(o2); + mdc->fetchMedia(o3); + mdc->fetchMedia(o4); + + int tick_num = 0; + + ensure(STR(tick_num) + ". is in queue 1", mdc->isInQueue(o1)); + ensure(STR(tick_num) + ". is in queue 2", mdc->isInQueue(o2)); + ensure(STR(tick_num) + ". is in queue 3", mdc->isInQueue(o3)); + ensure(STR(tick_num) + ". is in queue 4", mdc->isInQueue(o4)); + ensure(STR(tick_num) + ". post records", gPostRecords->size(), 0); + + ::pump_timers(); + ++tick_num; + + // The first tick should remove the first one + ensure(STR(tick_num) + ". is not in queue 1", !mdc->isInQueue(o1)); + ensure(STR(tick_num) + ". is in queue 2", mdc->isInQueue(o2)); + ensure(STR(tick_num) + ". is in queue 3", mdc->isInQueue(o3)); + ensure(STR(tick_num) + ". is in queue 4", mdc->isInQueue(o4)); + ensure(STR(tick_num) + ". post records", gPostRecords->size(), 1); + + // Now, pretend that object 4 moved relative to the avatar such + // that it is now closest + object4->setMediaInterest(50.0); + + ::pump_timers(); + ++tick_num; + + // The second tick should still pick off item 2, but then re-sort + // have picked off object 4 + ensure(STR(tick_num) + ". is in queue 2", mdc->isInQueue(o2)); + ensure(STR(tick_num) + ". is in queue 3", mdc->isInQueue(o3)); + ensure(STR(tick_num) + ". is not in queue 4", !mdc->isInQueue(o4)); + ensure(STR(tick_num) + ". post records", gPostRecords->size(), 2); + + ::pump_timers(); + ++tick_num; + + // The third tick should pick off object 2 + ensure(STR(tick_num) + ". is not in queue 2", !mdc->isInQueue(o2)); + ensure(STR(tick_num) + ". is in queue 3", mdc->isInQueue(o3)); + ensure(STR(tick_num) + ". post records", gPostRecords->size(), 3); + + // The fourth tick should pick off object 3 + ::pump_timers(); + ++tick_num; + + ensure(STR(tick_num) + ". is not in queue 3", !mdc->isInQueue(o3)); + ensure(STR(tick_num) + ". post records", gPostRecords->size(), 4); + + ensure("queue empty", mdc->isEmpty()); + } + ensure("refcount of o1", o1->getNumRefs(), 1); + ensure("refcount of o2", o2->getNumRefs(), 1); + ensure("refcount of o3", o3->getNumRefs(), 1); + ensure("refcount of o4", o4->getNumRefs(), 1); + } + + + template<> template<> + void mediadataclient_object_t::test<10>() + { + // + // Test using the "round-robin" queue + // + LOG_TEST(10); + + LLMediaDataClientObject::ptr_t o1 = new LLMediaDataClientObjectTest(_DATA(VALID_OBJECT_ID_1,"1.0","true")); + LLMediaDataClientObject::ptr_t o2 = new LLMediaDataClientObjectTest(_DATA(VALID_OBJECT_ID_2,"2.0","true")); + LLMediaDataClientObject::ptr_t o3 = new LLMediaDataClientObjectTest(_DATA(VALID_OBJECT_ID_3,"3.0","false")); + LLMediaDataClientObject::ptr_t o4 = new LLMediaDataClientObjectTest(_DATA(VALID_OBJECT_ID_4,"4.0","false")); + { + LLPointer<LLObjectMediaDataClient> mdc = new LLObjectMediaDataClient(NO_PERIOD,NO_PERIOD); + + // queue up all 4 objects. The first two should be in the sorted + // queue [2 1], the second in the round-robin queue. The queues + // are serviced interleaved, so we should expect: + // 2, 3, 1, 4 + mdc->fetchMedia(o1); + mdc->fetchMedia(o2); + mdc->fetchMedia(o3); + mdc->fetchMedia(o4); + + int tick_num = 0; + + // 0 + ensure(STR(tick_num) + ". is in queue 1", mdc->isInQueue(o1)); + ensure(STR(tick_num) + ". is in queue 2", mdc->isInQueue(o2)); + ensure(STR(tick_num) + ". is in queue 3", mdc->isInQueue(o3)); + ensure(STR(tick_num) + ". is in queue 4", mdc->isInQueue(o4)); + ensure(STR(tick_num) + ". post records", gPostRecords->size(), 0); + + ::pump_timers(); + ++tick_num; + + // 1 The first tick should remove object 2 + ensure(STR(tick_num) + ". is in queue 1", mdc->isInQueue(o1)); + ensure(STR(tick_num) + ". is not in queue 2", !mdc->isInQueue(o2)); + ensure(STR(tick_num) + ". is in queue 3", mdc->isInQueue(o3)); + ensure(STR(tick_num) + ". is in queue 4", mdc->isInQueue(o4)); + ensure(STR(tick_num) + ". post records", gPostRecords->size(), 1); + ensure(STR(tick_num) + ". post object id", (*gPostRecords)[0]["body"][LLTextureEntry::OBJECT_ID_KEY].asUUID(), LLUUID(VALID_OBJECT_ID_2)); + + ::pump_timers(); + ++tick_num; + + // 2 The second tick should send object 3 + ensure(STR(tick_num) + ". is in queue 1", mdc->isInQueue(o1)); + ensure(STR(tick_num) + ". is not in queue 2", !mdc->isInQueue(o2)); + ensure(STR(tick_num) + ". is not in queue 3", !mdc->isInQueue(o3)); + ensure(STR(tick_num) + ". is in queue 4", mdc->isInQueue(o4)); + ensure(STR(tick_num) + ". post records", gPostRecords->size(), 2); + ensure(STR(tick_num) + ". post object id", (*gPostRecords)[1]["body"][LLTextureEntry::OBJECT_ID_KEY].asUUID(), LLUUID(VALID_OBJECT_ID_3)); + + ::pump_timers(); + ++tick_num; + + // 3 The third tick should remove object 1 + ensure(STR(tick_num) + ". is not in queue 1", !mdc->isInQueue(o1)); + ensure(STR(tick_num) + ". is not in queue 2", !mdc->isInQueue(o2)); + ensure(STR(tick_num) + ". is not in queue 3", !mdc->isInQueue(o3)); + ensure(STR(tick_num) + ". is in queue 4", mdc->isInQueue(o4)); + ensure(STR(tick_num) + ". post records", gPostRecords->size(), 3); + ensure(STR(tick_num) + ". post object id", (*gPostRecords)[2]["body"][LLTextureEntry::OBJECT_ID_KEY].asUUID(), LLUUID(VALID_OBJECT_ID_1)); + + ::pump_timers(); + ++tick_num; + + // 4 The fourth tick should send object 4 + ensure(STR(tick_num) + ". is not in queue 1", !mdc->isInQueue(o1)); + ensure(STR(tick_num) + ". is not in queue 2", !mdc->isInQueue(o2)); + ensure(STR(tick_num) + ". is not in queue 3", !mdc->isInQueue(o3)); + ensure(STR(tick_num) + ". is not in queue 4", !mdc->isInQueue(o4)); + ensure(STR(tick_num) + ". post records", gPostRecords->size(), 4); + ensure(STR(tick_num) + ". post object id", (*gPostRecords)[3]["body"][LLTextureEntry::OBJECT_ID_KEY].asUUID(), LLUUID(VALID_OBJECT_ID_4)); + + ::pump_timers(); + ++tick_num; + + // 5 The fifth tick should not change the state of anything. + ensure(STR(tick_num) + ". is not in queue 1", !mdc->isInQueue(o1)); + ensure(STR(tick_num) + ". is not in queue 2", !mdc->isInQueue(o2)); + ensure(STR(tick_num) + ". is not in queue 3", !mdc->isInQueue(o3)); + ensure(STR(tick_num) + ". is not in queue 4", !mdc->isInQueue(o4)); + ensure(STR(tick_num) + ". post records", gPostRecords->size(), 4); + + ::pump_timers(); + + // Whew....better be empty + ensure("queue empty", mdc->isEmpty()); + } + ensure("refcount of o1", o1->getNumRefs(), 1); + ensure("refcount of o2", o2->getNumRefs(), 1); + ensure("refcount of o3", o3->getNumRefs(), 1); + ensure("refcount of o4", o4->getNumRefs(), 1); + } + + + template<> template<> + void mediadataclient_object_t::test<11>() + { + // + // Test LLMediaDataClient's destructor + // + LOG_TEST(11); + + LLMediaDataClientObject::ptr_t o = new LLMediaDataClientObjectTest(DATA); + int num_refs_start = o->getNumRefs(); + { + LLPointer<LLObjectMediaDataClient> mdc = new LLObjectMediaDataClient(NO_PERIOD,NO_PERIOD); + mdc->fetchMedia(o); + // must tick enough times to clear refcount of mdc + ::pump_timers(); + } + // Make sure everyone's destroyed properly + ensure("REF COUNT", o->getNumRefs(), num_refs_start); + } + + template<> template<> + void mediadataclient_object_t::test<12>() + { + // + // Test the "not interesting enough" call + // + LOG_TEST(12); + + LLMediaDataClientObjectTest *object1 = new LLMediaDataClientObjectTest(_DATA(VALID_OBJECT_ID_1,"1.0","true")); + LLMediaDataClientObject::ptr_t o1 = object1; + LLMediaDataClientObject::ptr_t o2 = new LLMediaDataClientObjectTest(_DATA(VALID_OBJECT_ID_2,"2.0","true")); + LLMediaDataClientObject::ptr_t o3 = new LLMediaDataClientObjectTest(_DATA(VALID_OBJECT_ID_3,"3.0","true")); + LLMediaDataClientObject::ptr_t o4 = new LLMediaDataClientObjectTest(_DATA(VALID_OBJECT_ID_4,"4.0","true")); + { + LLPointer<LLObjectMediaDataClient> mdc = new LLObjectMediaDataClient(NO_PERIOD,NO_PERIOD); + + // queue up all 4 objects. The first two are "interesting enough". + // Firing the timer 4 times should therefore leave them. + // Note that they should be sorted 4,3,2,1 + // Then, we'll make one "interesting enough", fire the timer a few + // times, and make sure only it gets pulled off the queue + gMinimumInterestLevel = 2.5; + mdc->fetchMedia(o1); + mdc->fetchMedia(o2); + mdc->fetchMedia(o3); + mdc->fetchMedia(o4); + + int tick_num = 0; + + // 0 + ensure(STR(tick_num) + ". is in queue 1", mdc->isInQueue(o1)); + ensure(STR(tick_num) + ". is in queue 2", mdc->isInQueue(o2)); + ensure(STR(tick_num) + ". is in queue 3", mdc->isInQueue(o3)); + ensure(STR(tick_num) + ". is in queue 4", mdc->isInQueue(o4)); + ensure(STR(tick_num) + ". post records", gPostRecords->size(), 0); + + ::pump_timers(); + ++tick_num; + + // 1 The first tick should remove object 4 + ensure(STR(tick_num) + ". is in queue 1", mdc->isInQueue(o1)); + ensure(STR(tick_num) + ". is in queue 2", mdc->isInQueue(o2)); + ensure(STR(tick_num) + ". is in queue 3", mdc->isInQueue(o3)); + ensure(STR(tick_num) + ". is not in queue 4", !mdc->isInQueue(o4)); + ensure(STR(tick_num) + ". post records", gPostRecords->size(), 1); + ensure(STR(tick_num) + ". post object id", (*gPostRecords)[0]["body"][LLTextureEntry::OBJECT_ID_KEY].asUUID(), LLUUID(VALID_OBJECT_ID_4)); + + ::pump_timers(); + ++tick_num; + + // 2 The second tick should send object 3 + ensure(STR(tick_num) + ". is in queue 1", mdc->isInQueue(o1)); + ensure(STR(tick_num) + ". is in queue 2", mdc->isInQueue(o2)); + ensure(STR(tick_num) + ". is not in queue 3", !mdc->isInQueue(o3)); + ensure(STR(tick_num) + ". is not in queue 4", !mdc->isInQueue(o4)); + ensure(STR(tick_num) + ". post records", gPostRecords->size(), 2); + ensure(STR(tick_num) + ". post object id", (*gPostRecords)[1]["body"][LLTextureEntry::OBJECT_ID_KEY].asUUID(), LLUUID(VALID_OBJECT_ID_3)); + + ::pump_timers(); + ++tick_num; + + // 3 The third tick should not pull off anything + ensure(STR(tick_num) + ". is in queue 1", mdc->isInQueue(o1)); + ensure(STR(tick_num) + ". is in queue 2", mdc->isInQueue(o2)); + ensure(STR(tick_num) + ". is not in queue 3", !mdc->isInQueue(o3)); + ensure(STR(tick_num) + ". is not in queue 4", !mdc->isInQueue(o4)); + ensure(STR(tick_num) + ". post records", gPostRecords->size(), 2); + + ::pump_timers(); + ++tick_num; + + // 4 The fourth tick (for good measure) should not pull off anything + ensure(STR(tick_num) + ". is in queue 1", mdc->isInQueue(o1)); + ensure(STR(tick_num) + ". is in queue 2", mdc->isInQueue(o2)); + ensure(STR(tick_num) + ". is not in queue 3", !mdc->isInQueue(o3)); + ensure(STR(tick_num) + ". is not in queue 4", !mdc->isInQueue(o4)); + ensure(STR(tick_num) + ". post records", gPostRecords->size(), 2); + + // Okay, now futz with object 1's interest, such that it is now + // "interesting enough" + object1->setMediaInterest((F64)5.0); + + // This should sort so that the queue is now [1 2] + ::pump_timers(); + ++tick_num; + + // 5 The fifth tick should now identify objects 3 and 4 as no longer + // needing "updating", and remove them from the queue + ensure(STR(tick_num) + ". is not in queue 1", !mdc->isInQueue(o1)); + ensure(STR(tick_num) + ". is in queue 2", mdc->isInQueue(o2)); + ensure(STR(tick_num) + ". is not in queue 3", !mdc->isInQueue(o3)); + ensure(STR(tick_num) + ". is not in queue 4", !mdc->isInQueue(o4)); + ensure(STR(tick_num) + ". post records", gPostRecords->size(), 3); + ensure(STR(tick_num) + ". post object id", (*gPostRecords)[2]["body"][LLTextureEntry::OBJECT_ID_KEY].asUUID(), LLUUID(VALID_OBJECT_ID_1)); + + ::pump_timers(); + ++tick_num; + + // 6 The sixth tick should not pull off anything + ensure(STR(tick_num) + ". is not in queue 1", !mdc->isInQueue(o1)); + ensure(STR(tick_num) + ". is in queue 2", mdc->isInQueue(o2)); + ensure(STR(tick_num) + ". is not in queue 3", !mdc->isInQueue(o3)); + ensure(STR(tick_num) + ". is not in queue 4", !mdc->isInQueue(o4)); + ensure(STR(tick_num) + ". post records", gPostRecords->size(), 3); + + ::pump_timers(); + ++tick_num; + + // Whew....better NOT be empty ... o2 should still be there + ensure("queue not empty", !mdc->isEmpty()); + + // But, we need to clear the queue, or else we won't destroy MDC... + // this is a strange interplay between the queue timer and the MDC + mdc->removeFromQueue(o2); + // tick + ::pump_timers(); + } + ensure("refcount of o1", o1->getNumRefs(), 1); + ensure("refcount of o2", o2->getNumRefs(), 1); + ensure("refcount of o3", o3->getNumRefs(), 1); + ensure("refcount of o4", o4->getNumRefs(), 1); + } + + template<> template<> + void mediadataclient_object_t::test<13>() + { + // + // Test supression of redundant navigates. + // + LOG_TEST(13); + + LLMediaDataClientObject::ptr_t o1 = new LLMediaDataClientObjectTest(_DATA(VALID_OBJECT_ID_1,"1.0","true")); + { + LLPointer<LLObjectMediaNavigateClient> mdc = new LLObjectMediaNavigateClient(NO_PERIOD,NO_PERIOD); + const char *TEST_URL = "http://foo.example.com"; + const char *TEST_URL_2 = "http://example.com"; + mdc->navigate(o1, 0, TEST_URL); + mdc->navigate(o1, 1, TEST_URL); + mdc->navigate(o1, 0, TEST_URL_2); + mdc->navigate(o1, 1, TEST_URL_2); + + // This should add two requests to the queue, one for face 0 of the object and one for face 1. + + ensure("before pump: 1 is in queue", mdc->isInQueue(o1)); + + ::pump_timers(); + + ensure("after first pump: 1 is in queue", mdc->isInQueue(o1)); + + ::pump_timers(); + + ensure("after second pump: 1 is not in queue", !mdc->isInQueue(o1)); + + ensure("first post has correct url", (*gPostRecords)[0]["body"][LLMediaEntry::CURRENT_URL_KEY].asString(), std::string(TEST_URL_2)); + ensure("second post has correct url", (*gPostRecords)[1]["body"][LLMediaEntry::CURRENT_URL_KEY].asString(), std::string(TEST_URL_2)); + + } + } + +} diff --git a/indra/newview/tests/llremoteparcelrequest_test.cpp b/indra/newview/tests/llremoteparcelrequest_test.cpp new file mode 100644 index 0000000000..ed66066b0a --- /dev/null +++ b/indra/newview/tests/llremoteparcelrequest_test.cpp @@ -0,0 +1,134 @@ +/** + * @file llremoteparcelrequest_test.cpp + * @author Brad Kittenbrink <brad@lindenlab.com> + * + * $LicenseInfo:firstyear=2010&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "linden_common.h" + +#include "../test/lltut.h" + +#include "../llremoteparcelrequest.h" + +#include "../llagent.h" +#include "message.h" +#include "llurlentry.h" + +namespace { + const LLUUID TEST_PARCEL_ID("11111111-1111-1111-1111-111111111111"); +} + +LLCurl::Responder::Responder() { } +LLCurl::Responder::~Responder() { } +void LLCurl::Responder::error(U32,std::string const &) { } +void LLCurl::Responder::result(LLSD const &) { } +void LLCurl::Responder::errorWithContent(U32 status,std::string const &,LLSD const &) { } +void LLCurl::Responder::completedRaw(U32 status, std::string const &, LLChannelDescriptors const &,boost::shared_ptr<LLBufferArray> const &) { } +void LLCurl::Responder::completed(U32 status, std::string const &, LLSD const &) { } +void LLCurl::Responder::completedHeader(U32 status, std::string const &, LLSD const &) { } +void LLMessageSystem::getF32(char const *,char const *,F32 &,S32) { } +void LLMessageSystem::getU8(char const *,char const *,U8 &,S32) { } +void LLMessageSystem::getS32(char const *,char const *,S32 &,S32) { } +void LLMessageSystem::getString(char const *,char const *, std::string &,S32) { } +void LLMessageSystem::getUUID(char const *,char const *, LLUUID & out_id,S32) +{ + out_id = TEST_PARCEL_ID; +} +void LLMessageSystem::nextBlock(char const *) { } +void LLMessageSystem::addUUID(char const *,LLUUID const &) { } +void LLMessageSystem::addUUIDFast(char const *,LLUUID const &) { } +void LLMessageSystem::nextBlockFast(char const *) { } +void LLMessageSystem::newMessage(char const *) { } +LLMessageSystem * gMessageSystem; +char const* const _PREHASH_AgentID = 0; // never dereferenced during this test +char const* const _PREHASH_AgentData = 0; // never dereferenced during this test +LLAgent gAgent; +LLAgent::LLAgent() : mAgentAccess(NULL) { } +LLAgent::~LLAgent() { } +void LLAgent::sendReliableMessage(void) { } +LLUUID gAgentSessionID; +LLUUID gAgentID; +LLUIColor::LLUIColor(void) { } +LLControlGroup::LLControlGroup(std::string const & name) : LLInstanceTracker<LLControlGroup, std::string>(name) { } +LLControlGroup::~LLControlGroup(void) { } +void LLUrlEntryParcel::processParcelInfo(const LLUrlEntryParcel::LLParcelData& parcel_data) { } + +namespace tut +{ + struct TestObserver : public LLRemoteParcelInfoObserver { + TestObserver() : mProcessed(false) { } + + virtual void processParcelInfo(const LLParcelData& parcel_data) + { + mProcessed = true; + } + + virtual void setParcelID(const LLUUID& parcel_id) { } + + virtual void setErrorStatus(U32 status, const std::string& reason) { } + + bool mProcessed; + }; + + struct RemoteParcelRequestData + { + RemoteParcelRequestData() + { + } + }; + + typedef test_group<RemoteParcelRequestData> remoteparcelrequest_t; + typedef remoteparcelrequest_t::object remoteparcelrequest_object_t; + tut::remoteparcelrequest_t tut_remoteparcelrequest("LLRemoteParcelRequest"); + + template<> template<> + void remoteparcelrequest_object_t::test<1>() + { + set_test_name("observer pointer"); + + boost::scoped_ptr<TestObserver> observer(new TestObserver()); + + LLRemoteParcelInfoProcessor & processor = LLRemoteParcelInfoProcessor::instance(); + processor.addObserver(LLUUID(TEST_PARCEL_ID), observer.get()); + + processor.processParcelInfoReply(gMessageSystem, NULL); + + ensure(observer->mProcessed); + } + + template<> template<> + void remoteparcelrequest_object_t::test<2>() + { + set_test_name("CHOP-220: dangling observer pointer"); + + LLRemoteParcelInfoObserver * observer = new TestObserver(); + + LLRemoteParcelInfoProcessor & processor = LLRemoteParcelInfoProcessor::instance(); + processor.addObserver(LLUUID(TEST_PARCEL_ID), observer); + + delete observer; + observer = NULL; + + processor.processParcelInfoReply(gMessageSystem, NULL); + } +} diff --git a/indra/newview/tests/llsecapi_test.cpp b/indra/newview/tests/llsecapi_test.cpp new file mode 100644 index 0000000000..703603e2db --- /dev/null +++ b/indra/newview/tests/llsecapi_test.cpp @@ -0,0 +1,122 @@ +/** + * @file llsecapi_test.cpp + * @author Roxie + * @date 2009-02-10 + * @brief Test the sec api functionality + * + * $LicenseInfo:firstyear=2009&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ +#include "../llviewerprecompiledheaders.h" +#include "../llviewernetwork.h" +#include "../test/lltut.h" +#include "../llsecapi.h" +#include "../llsechandler_basic.h" +#include "../../llxml/llcontrol.h" + + +//---------------------------------------------------------------------------- +// Mock objects for the dependencies of the code we're testing + +LLControlGroup::LLControlGroup(const std::string& name) +: LLInstanceTracker<LLControlGroup, std::string>(name) {} +LLControlGroup::~LLControlGroup() {} +BOOL LLControlGroup::declareString(const std::string& name, + const std::string& initial_val, + const std::string& comment, + BOOL persist) {return TRUE;} +void LLControlGroup::setString(const std::string& name, const std::string& val){} +std::string LLControlGroup::getString(const std::string& name) +{ + return ""; +} + + +LLControlGroup gSavedSettings("test"); + +LLSecAPIBasicHandler::LLSecAPIBasicHandler() {} +void LLSecAPIBasicHandler::init() {} +LLSecAPIBasicHandler::~LLSecAPIBasicHandler() {} +LLPointer<LLCertificate> LLSecAPIBasicHandler::getCertificate(const std::string& pem_cert) { return NULL; } +LLPointer<LLCertificate> LLSecAPIBasicHandler::getCertificate(X509* openssl_cert) { return NULL; } +LLPointer<LLCertificateChain> LLSecAPIBasicHandler::getCertificateChain(const X509_STORE_CTX* chain) { return NULL; } +LLPointer<LLCertificateStore> LLSecAPIBasicHandler::getCertificateStore(const std::string& store_id) { return NULL; } +void LLSecAPIBasicHandler::setProtectedData(const std::string& data_type, const std::string& data_id, const LLSD& data) {} +LLSD LLSecAPIBasicHandler::getProtectedData(const std::string& data_type, const std::string& data_id) { return LLSD(); } +void LLSecAPIBasicHandler::deleteProtectedData(const std::string& data_type, const std::string& data_id) {} +LLPointer<LLCredential> LLSecAPIBasicHandler::createCredential(const std::string& grid, const LLSD& identifier, const LLSD& authenticator) { return NULL; } +LLPointer<LLCredential> LLSecAPIBasicHandler::loadCredential(const std::string& grid) { return NULL; } +void LLSecAPIBasicHandler::saveCredential(LLPointer<LLCredential> cred, bool save_authenticator) {} +void LLSecAPIBasicHandler::deleteCredential(LLPointer<LLCredential> cred) {} + +// ------------------------------------------------------------------------------------------- +// TUT +// ------------------------------------------------------------------------------------------- +namespace tut +{ + // Test wrapper declaration : wrapping nothing for the moment + struct secapiTest + { + + secapiTest() + { + } + ~secapiTest() + { + } + }; + + // Tut templating thingamagic: test group, object and test instance + typedef test_group<secapiTest> secapiTestFactory; + typedef secapiTestFactory::object secapiTestObject; + tut::secapiTestFactory tut_test("LLSecAPI"); + + // --------------------------------------------------------------------------------------- + // Test functions + // --------------------------------------------------------------------------------------- + // registration + template<> template<> + void secapiTestObject::test<1>() + { + // retrieve an unknown handler + + ensure("'Unknown' handler should be NULL", !(BOOL)getSecHandler("unknown")); + LLPointer<LLSecAPIHandler> test1_handler = new LLSecAPIBasicHandler(); + registerSecHandler("sectest1", test1_handler); + ensure("'Unknown' handler should be NULL", !(BOOL)getSecHandler("unknown")); + LLPointer<LLSecAPIHandler> retrieved_test1_handler = getSecHandler("sectest1"); + ensure("Retrieved sectest1 handler should be the same", + retrieved_test1_handler == test1_handler); + + // insert a second handler + LLPointer<LLSecAPIHandler> test2_handler = new LLSecAPIBasicHandler(); + registerSecHandler("sectest2", test2_handler); + ensure("'Unknown' handler should be NULL", !(BOOL)getSecHandler("unknown")); + retrieved_test1_handler = getSecHandler("sectest1"); + ensure("Retrieved sectest1 handler should be the same", + retrieved_test1_handler == test1_handler); + + LLPointer<LLSecAPIHandler> retrieved_test2_handler = getSecHandler("sectest2"); + ensure("Retrieved sectest1 handler should be the same", + retrieved_test2_handler == test2_handler); + + } +} diff --git a/indra/newview/tests/llsechandler_basic_test.cpp b/indra/newview/tests/llsechandler_basic_test.cpp new file mode 100644 index 0000000000..daa10819fc --- /dev/null +++ b/indra/newview/tests/llsechandler_basic_test.cpp @@ -0,0 +1,1065 @@ +/** + * @file llsechandler_basic_test.cpp + * @author Roxie + * @date 2009-02-10 + * @brief Test the 'basic' sec handler functions + * + * $LicenseInfo:firstyear=2005&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ +#include "../llviewerprecompiledheaders.h" +#include "../test/lltut.h" +#include "../llsecapi.h" +#include "../llsechandler_basic.h" +#include "../../llxml/llcontrol.h" +#include "../llviewernetwork.h" +#include "lluuid.h" +#include "llxorcipher.h" +#include "apr_base64.h" +#include <vector> +#include <ios> +#include <llsdserialize.h> +#include <openssl/pem.h> +#include <openssl/err.h> +#include <openssl/evp.h> +#include "llxorcipher.h" +#include <openssl/ossl_typ.h> +#include <openssl/x509.h> +#include <openssl/x509v3.h> +#include <openssl/pem.h> +#include <openssl/asn1.h> +#include <openssl/rand.h> +#include <openssl/err.h> +#include "../llmachineid.h" + +#define ensure_throws(str, exc_type, cert, func, ...) \ +try \ +{ \ +func(__VA_ARGS__); \ +fail("throws, " str); \ +} \ +catch(exc_type& except) \ +{ \ +ensure("Exception cert is incorrect for " str, except.getCert() == cert); \ +} + +extern bool _cert_hostname_wildcard_match(const std::string& hostname, const std::string& wildcard_string); + +//---------------------------------------------------------------------------- +// Mock objects for the dependencies of the code we're testing + +std::string gFirstName; +std::string gLastName; +LLControlGroup::LLControlGroup(const std::string& name) +: LLInstanceTracker<LLControlGroup, std::string>(name) {} +LLControlGroup::~LLControlGroup() {} +BOOL LLControlGroup::declareString(const std::string& name, + const std::string& initial_val, + const std::string& comment, + BOOL persist) {return TRUE;} +void LLControlGroup::setString(const std::string& name, const std::string& val){} +std::string LLControlGroup::getString(const std::string& name) +{ + + if (name == "FirstName") + return gFirstName; + else if (name == "LastName") + return gLastName; + return ""; +} + +LLSD LLCredential::getLoginParams() +{ + LLSD result = LLSD::emptyMap(); + + // legacy credential + result["passwd"] = "$1$testpasssd"; + result["first"] = "myfirst"; + result["last"] ="mylast"; + return result; +} + +void LLCredential::identifierType(std::string &idType) +{ +} + +void LLCredential::authenticatorType(std::string &idType) +{ +} + + +LLControlGroup gSavedSettings("test"); +unsigned char gMACAddress[MAC_ADDRESS_BYTES] = {77,21,46,31,89,2}; + + +S32 LLMachineID::getUniqueID(unsigned char *unique_id, size_t len) +{ + memcpy(unique_id, gMACAddress, len); + return 1; +} +S32 LLMachineID::init() { return 1; } + + +// ------------------------------------------------------------------------------------------- +// TUT +// ------------------------------------------------------------------------------------------- +namespace tut +{ + // Test wrapper declaration : wrapping nothing for the moment + struct sechandler_basic_test + { + std::string mPemTestCert, mPemRootCert, mPemIntermediateCert, mPemChildCert, mSha1RSATestCert, mSha1RSATestCA; + std::string mDerFormat; + X509 *mX509TestCert, *mX509RootCert, *mX509IntermediateCert, *mX509ChildCert; + + sechandler_basic_test() + { + LLMachineID::init(); + OpenSSL_add_all_algorithms(); + OpenSSL_add_all_ciphers(); + OpenSSL_add_all_digests(); + ERR_load_crypto_strings(); + gFirstName = ""; + gLastName = ""; + LLFile::remove("test_password.dat"); + LLFile::remove("sechandler_settings.tmp"); + mPemTestCert = "-----BEGIN CERTIFICATE-----\n" + "MIIEuDCCA6CgAwIBAgIBBDANBgkqhkiG9w0BAQUFADCBtDELMAkGA1UEBhMCQlIx\n" + "EzARBgNVBAoTCklDUC1CcmFzaWwxPTA7BgNVBAsTNEluc3RpdHV0byBOYWNpb25h\n" + "bCBkZSBUZWNub2xvZ2lhIGRhIEluZm9ybWFjYW8gLSBJVEkxETAPBgNVBAcTCEJy\n" + "YXNpbGlhMQswCQYDVQQIEwJERjExMC8GA1UEAxMoQXV0b3JpZGFkZSBDZXJ0aWZp\n" + "Y2Fkb3JhIFJhaXogQnJhc2lsZWlyYTAeFw0wMTExMzAxMjU4MDBaFw0xMTExMzAy\n" + "MzU5MDBaMIG0MQswCQYDVQQGEwJCUjETMBEGA1UEChMKSUNQLUJyYXNpbDE9MDsG\n" + "A1UECxM0SW5zdGl0dXRvIE5hY2lvbmFsIGRlIFRlY25vbG9naWEgZGEgSW5mb3Jt\n" + "YWNhbyAtIElUSTERMA8GA1UEBxMIQnJhc2lsaWExCzAJBgNVBAgTAkRGMTEwLwYD\n" + "VQQDEyhBdXRvcmlkYWRlIENlcnRpZmljYWRvcmEgUmFpeiBCcmFzaWxlaXJhMIIB\n" + "IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwPMudwX/hvm+Uh2b/lQAcHVA\n" + "isamaLkWdkwP9/S/tOKIgRrL6Oy+ZIGlOUdd6uYtk9Ma/3pUpgcfNAj0vYm5gsyj\n" + "Qo9emsc+x6m4VWwk9iqMZSCK5EQkAq/Ut4n7KuLE1+gdftwdIgxfUsPt4CyNrY50\n" + "QV57KM2UT8x5rrmzEjr7TICGpSUAl2gVqe6xaii+bmYR1QrmWaBSAG59LrkrjrYt\n" + "bRhFboUDe1DK+6T8s5L6k8c8okpbHpa9veMztDVC9sPJ60MWXh6anVKo1UcLcbUR\n" + "yEeNvZneVRKAAU6ouwdjDvwlsaKydFKwed0ToQ47bmUKgcm+wV3eTRk36UOnTwID\n" + "AQABo4HSMIHPME4GA1UdIARHMEUwQwYFYEwBAQAwOjA4BggrBgEFBQcCARYsaHR0\n" + "cDovL2FjcmFpei5pY3BicmFzaWwuZ292LmJyL0RQQ2FjcmFpei5wZGYwPQYDVR0f\n" + "BDYwNDAyoDCgLoYsaHR0cDovL2FjcmFpei5pY3BicmFzaWwuZ292LmJyL0xDUmFj\n" + "cmFpei5jcmwwHQYDVR0OBBYEFIr68VeEERM1kEL6V0lUaQ2kxPA3MA8GA1UdEwEB\n" + "/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBBQUAA4IBAQAZA5c1\n" + "U/hgIh6OcgLAfiJgFWpvmDZWqlV30/bHFpj8iBobJSm5uDpt7TirYh1Uxe3fQaGl\n" + "YjJe+9zd+izPRbBqXPVQA34EXcwk4qpWuf1hHriWfdrx8AcqSqr6CuQFwSr75Fos\n" + "SzlwDADa70mT7wZjAmQhnZx2xJ6wfWlT9VQfS//JYeIc7Fue2JNLd00UOSMMaiK/\n" + "t79enKNHEA2fupH3vEigf5Eh4bVAN5VohrTm6MY53x7XQZZr1ME7a55lFEnSeT0u\n" + "mlOAjR2mAbvSM5X5oSZNrmetdzyTj2flCM8CC7MLab0kkdngRIlUBGHF1/S5nmPb\n" + "K+9A46sd33oqK8n8\n" + "-----END CERTIFICATE-----\n"; + + mPemRootCert = "-----BEGIN CERTIFICATE-----\n" + "MIIB0TCCATqgAwIBAgIJANaTqrzEvHaRMA0GCSqGSIb3DQEBBAUAMBsxGTAXBgNV\n" + "BAMTEFJveGllcyB0ZXN0IHJvb3QwHhcNMDkwNDE1MjEwNzQ3WhcNMTAwNDE1MjEw\n" + "NzQ3WjAbMRkwFwYDVQQDExBSb3hpZXMgdGVzdCByb290MIGfMA0GCSqGSIb3DQEB\n" + "AQUAA4GNADCBiQKBgQCpo5nDW6RNz9IHUVZd7Tw2XAQiBniDF4xH0N1w7sUYTiFq\n" + "21mABsnOPJD3ra+MtOsXPHcaljm661JjTD8L40v5sfEbqDUPcOw76ClrPqnuAeyT\n" + "38qk8DHku/mT8YdprevGZdVcUXQg3vosVzOL93HOOHK+u61mEEoM9W5xoNVEdQID\n" + "AQABox0wGzAMBgNVHRMEBTADAQH/MAsGA1UdDwQEAwIBBjANBgkqhkiG9w0BAQQF\n" + "AAOBgQAzn0aW/+zWPmcTbvxonyiYYUr9b4SOB/quhAkT8KT4ir1dcZAXRR59+kEn\n" + "HSTu1FAodV0gvESqyobftF5hZ1XMxdJqGu//xP+YCwlv244G/0pp7KLI8ihNO2+N\n" + "lPBUJgbo++ZkhiE1jotZi9Ay0Oedh3s/AfbMZPyfpJ23ll6+BA==\n" + "-----END CERTIFICATE-----\n"; + + + + mPemIntermediateCert = "-----BEGIN CERTIFICATE-----\n" + "MIIBzzCCATigAwIBAgIBATANBgkqhkiG9w0BAQQFADAbMRkwFwYDVQQDExBSb3hp\n" + "ZXMgdGVzdCByb290MB4XDTA5MDQxNTIxMzE1NloXDTEwMDQxNTIxMzE1NlowITEf\n" + "MB0GA1UEAxMWUm94aWVzIGludGVybWVkaWF0ZSBDQTCBnzANBgkqhkiG9w0BAQEF\n" + "AAOBjQAwgYkCgYEA15MM0W1R37rx/24Q2Qkb5bSiQZxTUcQAhJ2pA8mwUucXuCVt\n" + "6ayI2TuN32nkjmsCgUkiT/bdXWp0OJo7/MXRIFeUNMCRxrpeFnxuigYEqbIXAdN6\n" + "qu/vdG2X4PRv/v9Ijrju4cBEiKIldIgOurWEIfXEsVSFP2XmFQHesF04qDcCAwEA\n" + "AaMdMBswDAYDVR0TBAUwAwEB/zALBgNVHQ8EBAMCAQYwDQYJKoZIhvcNAQEEBQAD\n" + "gYEAYljikYgak3W1jSo0vYthNHUy3lBVAKzDhpM96lY5OuXFslpCRX42zNL8X3kN\n" + "U/4IaJUVtZqx8WsUXl1eXHzBCaXCftapV4Ir6cENLIsXCdXs8paFYzN5nPJA5GYU\n" + "zWgkSEl1MEhNIc+bJW34vwi29EjrAShAhsIZ84Mt/lvD3Pc=\n" + "-----END CERTIFICATE-----\n"; + + mPemChildCert = "-----BEGIN CERTIFICATE-----\n" + "MIIB5DCCAU0CBEnm9eUwDQYJKoZIhvcNAQEEBQAwITEfMB0GA1UEAxMWUm94aWVz\n" + "IGludGVybWVkaWF0ZSBDQTAeFw0wOTA0MTYwMDAzNDlaFw0xMDA0MTYwMDAzNDla\n" + "MCAxHjAcBgNVBAMTFWVuaWFjNjMubGluZGVubGFiLmNvbTCBnzANBgkqhkiG9w0B\n" + "AQEFAAOBjQAwgYkCgYEAp9I5rofEzbjNht+9QejfnsIlEPqSxskoWKCG255TesWR\n" + "RTmw9wafHQQkJk/VIsaU4RMBYHkknGbHX2dGvMHmKZoWUPSQ/8FZz09o0Qx3TNUZ\n" + "l7KlGOD2d1c7ZxXDPqlLC6QW8DrE1/8zfwJ5cbYBXc8e7OKdSZeRrnwHyw4Q8r8C\n" + "AwEAAaMvMC0wEwYDVR0lBAwwCgYIKwYBBQUHAwEwCQYDVR0TBAIwADALBgNVHQ8E\n" + "BAMCBaAwDQYJKoZIhvcNAQEEBQADgYEAIG0M5tqYlXyMiGKPZfXy/R3M3ZZOapDk\n" + "W0dsXJYXAc35ftwtn0VYu9CNnZCcli17/d+AKhkK8a/oGPazqudjFF6WLJLTXaY9\n" + "NmhkJcOPADXkbyQPUPXzLe4YRrkEQeGhzMb4rKDQ1TKAcXfs0Y068pTpsixNSxja\n" + "NhAUUcve5Is=\n" + "-----END CERTIFICATE-----\n"; + + mDerFormat = "MIIEuDCCA6CgAwIBAgIBBDANBgkqhkiG9w0BAQUFADCBtDELMAkGA1UEBhMCQlIxEzARBgNVBAoT" +"CklDUC1CcmFzaWwxPTA7BgNVBAsTNEluc3RpdHV0byBOYWNpb25hbCBkZSBUZWNub2xvZ2lhIGRh" +"IEluZm9ybWFjYW8gLSBJVEkxETAPBgNVBAcTCEJyYXNpbGlhMQswCQYDVQQIEwJERjExMC8GA1UE" +"AxMoQXV0b3JpZGFkZSBDZXJ0aWZpY2Fkb3JhIFJhaXogQnJhc2lsZWlyYTAeFw0wMTExMzAxMjU4" +"MDBaFw0xMTExMzAyMzU5MDBaMIG0MQswCQYDVQQGEwJCUjETMBEGA1UEChMKSUNQLUJyYXNpbDE9" +"MDsGA1UECxM0SW5zdGl0dXRvIE5hY2lvbmFsIGRlIFRlY25vbG9naWEgZGEgSW5mb3JtYWNhbyAt" +"IElUSTERMA8GA1UEBxMIQnJhc2lsaWExCzAJBgNVBAgTAkRGMTEwLwYDVQQDEyhBdXRvcmlkYWRl" +"IENlcnRpZmljYWRvcmEgUmFpeiBCcmFzaWxlaXJhMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB" +"CgKCAQEAwPMudwX/hvm+Uh2b/lQAcHVAisamaLkWdkwP9/S/tOKIgRrL6Oy+ZIGlOUdd6uYtk9Ma" +"/3pUpgcfNAj0vYm5gsyjQo9emsc+x6m4VWwk9iqMZSCK5EQkAq/Ut4n7KuLE1+gdftwdIgxfUsPt" +"4CyNrY50QV57KM2UT8x5rrmzEjr7TICGpSUAl2gVqe6xaii+bmYR1QrmWaBSAG59LrkrjrYtbRhF" +"boUDe1DK+6T8s5L6k8c8okpbHpa9veMztDVC9sPJ60MWXh6anVKo1UcLcbURyEeNvZneVRKAAU6o" +"uwdjDvwlsaKydFKwed0ToQ47bmUKgcm+wV3eTRk36UOnTwIDAQABo4HSMIHPME4GA1UdIARHMEUw" +"QwYFYEwBAQAwOjA4BggrBgEFBQcCARYsaHR0cDovL2FjcmFpei5pY3BicmFzaWwuZ292LmJyL0RQ" +"Q2FjcmFpei5wZGYwPQYDVR0fBDYwNDAyoDCgLoYsaHR0cDovL2FjcmFpei5pY3BicmFzaWwuZ292" +"LmJyL0xDUmFjcmFpei5jcmwwHQYDVR0OBBYEFIr68VeEERM1kEL6V0lUaQ2kxPA3MA8GA1UdEwEB" +"/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBBQUAA4IBAQAZA5c1U/hgIh6OcgLA" +"fiJgFWpvmDZWqlV30/bHFpj8iBobJSm5uDpt7TirYh1Uxe3fQaGlYjJe+9zd+izPRbBqXPVQA34E" +"Xcwk4qpWuf1hHriWfdrx8AcqSqr6CuQFwSr75FosSzlwDADa70mT7wZjAmQhnZx2xJ6wfWlT9VQf" +"S//JYeIc7Fue2JNLd00UOSMMaiK/t79enKNHEA2fupH3vEigf5Eh4bVAN5VohrTm6MY53x7XQZZr" +"1ME7a55lFEnSeT0umlOAjR2mAbvSM5X5oSZNrmetdzyTj2flCM8CC7MLab0kkdngRIlUBGHF1/S5" +"nmPbK+9A46sd33oqK8n8"; + + mSha1RSATestCert = "-----BEGIN CERTIFICATE-----\n" + "MIIDFDCCAn2gAwIBAgIDDqqYMA0GCSqGSIb3DQEBBQUAME4xCzAJBgNVBAYTAlVT\n" + "MRAwDgYDVQQKEwdFcXVpZmF4MS0wKwYDVQQLEyRFcXVpZmF4IFNlY3VyZSBDZXJ0\n" + "aWZpY2F0ZSBBdXRob3JpdHkwHhcNMTAwMTA1MDAzNjMwWhcNMTEwMTA3MjAyMTE0\n" + "WjCBnjEpMCcGA1UEBRMgQmNmc0RBRkl1U0YwdFpWVm5vOFJKbjVUbW9hNGR2Wkgx\n" + "CzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1TYW4g\n" + "RnJhbmNpc2NvMR0wGwYDVQQKExRMaW5kZW4gUmVzZWFyY2ggSW5jLjEYMBYGA1UE\n" + "AxQPKi5saW5kZW5sYWIuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQD2\n" + "14Jdko8v6GB33hHbW+lNQyloFQtc2h4ykjf+fYPJ27dw6tQO2if7N3k/5XDkwC1N\n" + "krGgE9vt3iecCPgasue6k67Zyfj9HbEP2D+j38eROudrsxLaRFDQx50BvZ5YMNl3\n" + "4zQCj8/gCMsuq8cvaP9/rbJTUpgYWFGLsm8yAYOgWwIDAQABo4GuMIGrMA4GA1Ud\n" + "DwEB/wQEAwIE8DAdBgNVHQ4EFgQUIBK/JB9AyqquSEbkzt2Zux6v9sYwOgYDVR0f\n" + "BDMwMTAvoC2gK4YpaHR0cDovL2NybC5nZW90cnVzdC5jb20vY3Jscy9zZWN1cmVj\n" + "YS5jcmwwHwYDVR0jBBgwFoAUSOZo+SvSspXXR9gjIBBPM5iQn9QwHQYDVR0lBBYw\n" + "FAYIKwYBBQUHAwEGCCsGAQUFBwMCMA0GCSqGSIb3DQEBBQUAA4GBAKKR84+hvLuB\n" + "pop9VG7HQPIyEKtZq3Nnk+UlJGfjGY3csLWSFmxU727r5DzdEP1W1PwF3rxuoKcZ\n" + "4nJJpKdzoGVujgBMP2U/J0PJvU7D8U3Zqu7nrXAjOHj7iVnvJ3EKJ1bvwXaisgPN\n" + "wt21kKfGnA4OlhJtJ6VQvUkcF12I3pTP\n" + "-----END CERTIFICATE-----\n"; + + mSha1RSATestCA = "-----BEGIN CERTIFICATE-----\n" + "MIIDIDCCAomgAwIBAgIENd70zzANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQGEwJV\n" + "UzEQMA4GA1UEChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUgQ2Vy\n" + "dGlmaWNhdGUgQXV0aG9yaXR5MB4XDTk4MDgyMjE2NDE1MVoXDTE4MDgyMjE2NDE1\n" + "MVowTjELMAkGA1UEBhMCVVMxEDAOBgNVBAoTB0VxdWlmYXgxLTArBgNVBAsTJEVx\n" + "dWlmYXggU2VjdXJlIENlcnRpZmljYXRlIEF1dGhvcml0eTCBnzANBgkqhkiG9w0B\n" + "AQEFAAOBjQAwgYkCgYEAwV2xWGcIYu6gmi0fCG2RFGiYCh7+2gRvE4RiIcPRfM6f\n" + "BeC4AfBONOziipUEZKzxa1NfBbPLZ4C/QgKO/t0BCezhABRP/PvwDN1Dulsr4R+A\n" + "cJkVV5MW8Q+XarfCaCMczE1ZMKxRHjuvK9buY0V7xdlfUNLjUA86iOe/FP3gx7kC\n" + "AwEAAaOCAQkwggEFMHAGA1UdHwRpMGcwZaBjoGGkXzBdMQswCQYDVQQGEwJVUzEQ\n" + "MA4GA1UEChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUgQ2VydGlm\n" + "aWNhdGUgQXV0aG9yaXR5MQ0wCwYDVQQDEwRDUkwxMBoGA1UdEAQTMBGBDzIwMTgw\n" + "ODIyMTY0MTUxWjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAUSOZo+SvSspXXR9gj\n" + "IBBPM5iQn9QwHQYDVR0OBBYEFEjmaPkr0rKV10fYIyAQTzOYkJ/UMAwGA1UdEwQF\n" + "MAMBAf8wGgYJKoZIhvZ9B0EABA0wCxsFVjMuMGMDAgbAMA0GCSqGSIb3DQEBBQUA\n" + "A4GBAFjOKer89961zgK5F7WF0bnj4JXMJTENAKaSbn+2kmOeUJXRmm/kEd5jhW6Y\n" + "7qj/WsjTVbJmcVfewCHrPSqnI0kBBIZCe/zuf6IWUrVnZ9NA2zsmWLIodz2uFHdh\n" + "1voqZiegDfqnc1zqcPGUIWVEX/r87yloqaKHee9570+sB3c4\n" + "-----END CERTIFICATE-----\n"; + + + + + mX509TestCert = NULL; + mX509RootCert = NULL; + mX509IntermediateCert = NULL; + mX509ChildCert = NULL; + + BIO * validation_bio = BIO_new_mem_buf((void*)mPemTestCert.c_str(), mPemTestCert.length()); + PEM_read_bio_X509(validation_bio, &mX509TestCert, 0, NULL); + BIO_free(validation_bio); + validation_bio = BIO_new_mem_buf((void*)mPemRootCert.c_str(), mPemRootCert.length()); + PEM_read_bio_X509(validation_bio, &mX509RootCert, 0, NULL); + BIO_free(validation_bio); + validation_bio = BIO_new_mem_buf((void*)mPemIntermediateCert.c_str(), mPemIntermediateCert.length()); + PEM_read_bio_X509(validation_bio, &mX509IntermediateCert, 0, NULL); + BIO_free(validation_bio); + validation_bio = BIO_new_mem_buf((void*)mPemChildCert.c_str(), mPemChildCert.length()); + PEM_read_bio_X509(validation_bio, &mX509ChildCert, 0, NULL); + BIO_free(validation_bio); + } + ~sechandler_basic_test() + { + LLFile::remove("test_password.dat"); + LLFile::remove("sechandler_settings.tmp"); + LLFile::remove("mycertstore.pem"); + X509_free(mX509TestCert); + X509_free(mX509RootCert); + X509_free(mX509IntermediateCert); + X509_free(mX509ChildCert); + } + }; + + // Tut templating thingamagic: test group, object and test instance + typedef test_group<sechandler_basic_test> sechandler_basic_test_factory; + typedef sechandler_basic_test_factory::object sechandler_basic_test_object; + tut::sechandler_basic_test_factory tut_test("LLSecHandler"); + + // --------------------------------------------------------------------------------------- + // Test functions + // --------------------------------------------------------------------------------------- + // test cert data retrieval + template<> template<> + void sechandler_basic_test_object::test<1>() + + { + char buffer[4096]; + LLPointer<LLCertificate> test_cert = new LLBasicCertificate(mPemTestCert); + + ensure_equals("Resultant pem is correct", + mPemTestCert, test_cert->getPem()); + std::vector<U8> binary_cert = test_cert->getBinary(); + + apr_base64_encode(buffer, (const char *)&binary_cert[0], binary_cert.size()); + + ensure_equals("Der Format is correct", memcmp(buffer, mDerFormat.c_str(), mDerFormat.length()), 0); + + LLSD llsd_cert; + test_cert->getLLSD(llsd_cert); + std::ostringstream llsd_value; + llsd_value << LLSDOStreamer<LLSDNotationFormatter>(llsd_cert) << std::endl; + std::string llsd_cert_str = llsd_value.str(); + ensure_equals("Issuer Name/commonName", + (std::string)llsd_cert["issuer_name"]["commonName"], "Autoridade Certificadora Raiz Brasileira"); + ensure_equals("Issure Name/countryName", (std::string)llsd_cert["issuer_name"]["countryName"], "BR"); + ensure_equals("Issuer Name/localityName", (std::string)llsd_cert["issuer_name"]["localityName"], "Brasilia"); + ensure_equals("Issuer Name/org name", (std::string)llsd_cert["issuer_name"]["organizationName"], "ICP-Brasil"); + ensure_equals("IssuerName/org unit", + (std::string)llsd_cert["issuer_name"]["organizationalUnitName"], "Instituto Nacional de Tecnologia da Informacao - ITI"); + ensure_equals("IssuerName/state", (std::string)llsd_cert["issuer_name"]["stateOrProvinceName"], "DF"); + ensure_equals("Issuer name string", + (std::string)llsd_cert["issuer_name_string"], "CN=Autoridade Certificadora Raiz Brasileira,ST=DF," + "L=Brasilia,OU=Instituto Nacional de Tecnologia da Informacao - ITI,O=ICP-Brasil,C=BR"); + ensure_equals("subject Name/commonName", + (std::string)llsd_cert["subject_name"]["commonName"], "Autoridade Certificadora Raiz Brasileira"); + ensure_equals("subject Name/countryName", (std::string)llsd_cert["subject_name"]["countryName"], "BR"); + ensure_equals("subject Name/localityName", (std::string)llsd_cert["subject_name"]["localityName"], "Brasilia"); + ensure_equals("subject Name/org name", (std::string)llsd_cert["subject_name"]["organizationName"], "ICP-Brasil"); + ensure_equals("subjectName/org unit", + (std::string)llsd_cert["subject_name"]["organizationalUnitName"], "Instituto Nacional de Tecnologia da Informacao - ITI"); + ensure_equals("subjectName/state", (std::string)llsd_cert["subject_name"]["stateOrProvinceName"], "DF"); + ensure_equals("subject name string", + (std::string)llsd_cert["subject_name_string"], "CN=Autoridade Certificadora Raiz Brasileira,ST=DF," + "L=Brasilia,OU=Instituto Nacional de Tecnologia da Informacao - ITI,O=ICP-Brasil,C=BR"); + + ensure_equals("md5 digest", (std::string)llsd_cert["md5_digest"], "96:89:7d:61:d1:55:2b:27:e2:5a:39:b4:2a:6c:44:6f"); + ensure_equals("serial number", (std::string)llsd_cert["serial_number"], "04"); + // sha1 digest is giving a weird value, and I've no idea why...feh + //ensure_equals("sha1 digest", (std::string)llsd_cert["sha1_digest"], "8e:fd:ca:bc:93:e6:1e:92:5d:4d:1d:ed:18:1a:43:20:a4:67:a1:39"); + ensure_equals("valid from", (std::string)llsd_cert["valid_from"], "2001-11-30T12:58:00Z"); + ensure_equals("valid to", (std::string)llsd_cert["valid_to"], "2011-11-30T23:59:00Z"); + LLSD expectedKeyUsage = LLSD::emptyArray(); + expectedKeyUsage.append(LLSD((std::string)"certSigning")); + expectedKeyUsage.append(LLSD((std::string)"crlSigning")); + ensure("key usage", valueCompareLLSD(llsd_cert["keyUsage"], expectedKeyUsage)); + ensure("basic constraints", (bool)llsd_cert["basicConstraints"]["CA"]); + + ensure("x509 is equal", !X509_cmp(mX509TestCert, test_cert->getOpenSSLX509())); + } + + + // test protected data + template<> template<> + void sechandler_basic_test_object::test<2>() + + { + + std::string protected_data = "sUSh3wj77NG9oAMyt3XIhaej3KLZhLZWFZvI6rIGmwUUOmmelrRg0NI9rkOj8ZDpTPxpwToaBT5u" + "GQhakdaGLJznr9bHr4/6HIC1bouKj4n2rs4TL6j2WSjto114QdlNfLsE8cbbE+ghww58g8SeyLQO" + "nyzXoz+/PBz0HD5SMFDuObccoPW24gmqYySz8YoEWhSwO0pUtEEqOjVRsAJgF5wLAtJZDeuilGsq" + "4ZT9Y4wZ9Rh8nnF3fDUL6IGamHe1ClXM1jgBu10F6UMhZbnH4C3aJ2E9+LiOntU+l3iCb2MpkEpr" + "82r2ZAMwIrpnirL/xoYoyz7MJQYwUuMvBPToZJrxNSsjI+S2Z+I3iEJAELMAAA=="; + + std::vector<U8> binary_data(apr_base64_decode_len(protected_data.c_str())); + apr_base64_decode_binary(&binary_data[0], protected_data.c_str()); + + LLXORCipher cipher(gMACAddress, MAC_ADDRESS_BYTES); + cipher.decrypt(&binary_data[0], 16); + unsigned char unique_id[MAC_ADDRESS_BYTES]; + LLMachineID::getUniqueID(unique_id, sizeof(unique_id)); + LLXORCipher cipher2(unique_id, sizeof(unique_id)); + cipher2.encrypt(&binary_data[0], 16); + std::ofstream temp_file("sechandler_settings.tmp", std::ofstream::binary); + temp_file.write((const char *)&binary_data[0], binary_data.size()); + temp_file.close(); + + LLPointer<LLSecAPIBasicHandler> handler = new LLSecAPIBasicHandler("sechandler_settings.tmp", + "test_password.dat"); + handler->init(); + // data retrieval for existing data + LLSD data = handler->getProtectedData("test_data_type", "test_data_id"); + + + ensure_equals("retrieve existing data1", (std::string)data["data1"], "test_data_1"); + ensure_equals("retrieve existing data2", (std::string)data["data2"], "test_data_2"); + ensure_equals("retrieve existing data3", (std::string)data["data3"]["elem1"], "test element1"); + + // data storage + LLSD store_data = LLSD::emptyMap(); + store_data["store_data1"] = "test_store_data1"; + store_data["store_data2"] = 27; + store_data["store_data3"] = LLSD::emptyMap(); + store_data["store_data3"]["subelem1"] = "test_subelem1"; + + handler->setProtectedData("test_data_type", "test_data_id1", store_data); + data = handler->getProtectedData("test_data_type", "test_data_id"); + + data = handler->getProtectedData("test_data_type", "test_data_id"); + // verify no overwrite of existing data + ensure_equals("verify no overwrite 1", (std::string)data["data1"], "test_data_1"); + ensure_equals("verify no overwrite 2", (std::string)data["data2"], "test_data_2"); + ensure_equals("verify no overwrite 3", (std::string)data["data3"]["elem1"], "test element1"); + + // verify written data is good + data = handler->getProtectedData("test_data_type", "test_data_id1"); + ensure_equals("verify stored data1", (std::string)data["store_data1"], "test_store_data1"); + ensure_equals("verify stored data2", (int)data["store_data2"], 27); + ensure_equals("verify stored data3", (std::string)data["store_data3"]["subelem1"], "test_subelem1"); + + // verify overwrite works + handler->setProtectedData("test_data_type", "test_data_id", store_data); + data = handler->getProtectedData("test_data_type", "test_data_id"); + ensure_equals("verify overwrite stored data1", (std::string)data["store_data1"], "test_store_data1"); + ensure_equals("verify overwrite stored data2", (int)data["store_data2"], 27); + ensure_equals("verify overwrite stored data3", (std::string)data["store_data3"]["subelem1"], "test_subelem1"); + + // verify other datatype doesn't conflict + store_data["store_data3"] = "test_store_data3"; + store_data["store_data4"] = 28; + store_data["store_data5"] = LLSD::emptyMap(); + store_data["store_data5"]["subelem2"] = "test_subelem2"; + + handler->setProtectedData("test_data_type1", "test_data_id", store_data); + data = handler->getProtectedData("test_data_type1", "test_data_id"); + ensure_equals("verify datatype stored data3", (std::string)data["store_data3"], "test_store_data3"); + ensure_equals("verify datatype stored data4", (int)data["store_data4"], 28); + ensure_equals("verify datatype stored data5", (std::string)data["store_data5"]["subelem2"], "test_subelem2"); + + // test data not found + + data = handler->getProtectedData("test_data_type1", "test_data_not_found"); + ensure("not found", data.isUndefined()); + + // cause a 'write' by using 'LLPointer' to delete then instantiate a handler + handler = NULL; + handler = new LLSecAPIBasicHandler("sechandler_settings.tmp", "test_password.dat"); + handler->init(); + + data = handler->getProtectedData("test_data_type1", "test_data_id"); + ensure_equals("verify datatype stored data3a", (std::string)data["store_data3"], "test_store_data3"); + ensure_equals("verify datatype stored data4a", (int)data["store_data4"], 28); + ensure_equals("verify datatype stored data5a", (std::string)data["store_data5"]["subelem2"], "test_subelem2"); + + // rewrite the initial file to verify reloads + handler = NULL; + std::ofstream temp_file2("sechandler_settings.tmp", std::ofstream::binary); + temp_file2.write((const char *)&binary_data[0], binary_data.size()); + temp_file2.close(); + + // cause a 'write' + handler = new LLSecAPIBasicHandler("sechandler_settings.tmp", "test_password.dat"); + handler->init(); + data = handler->getProtectedData("test_data_type1", "test_data_id"); + ensure("not found", data.isUndefined()); + + handler->deleteProtectedData("test_data_type", "test_data_id"); + ensure("Deleted data not found", handler->getProtectedData("test_data_type", "test_data_id").isUndefined()); + + LLFile::remove("sechandler_settings.tmp"); + handler = new LLSecAPIBasicHandler("sechandler_settings.tmp", "test_password.dat"); + handler->init(); + data = handler->getProtectedData("test_data_type1", "test_data_id"); + ensure("not found", data.isUndefined()); + handler = NULL; + + ensure(LLFile::isfile("sechandler_settings.tmp")); + } + + // test credenitals + template<> template<> + void sechandler_basic_test_object::test<3>() + { + LLPointer<LLSecAPIBasicHandler> handler = new LLSecAPIBasicHandler("sechandler_settings.tmp", "test_password.dat"); + handler->init(); + + LLSD my_id = LLSD::emptyMap(); + LLSD my_authenticator = LLSD::emptyMap(); + my_id["type"] = "test_type"; + my_id["username"] = "testuser@lindenlab.com"; + my_authenticator["type"] = "test_auth"; + my_authenticator["creds"] = "12345"; + + // test creation of credentials + LLPointer<LLCredential> my_cred = handler->createCredential("my_grid", my_id, my_authenticator); + + // test retrieval of credential components + ensure_equals("basic credential creation: identifier", my_id, my_cred->getIdentifier()); + ensure_equals("basic credential creation: authenticator", my_authenticator, my_cred->getAuthenticator()); + ensure_equals("basic credential creation: grid", "my_grid", my_cred->getGrid()); + + // test setting/overwriting of credential components + my_id["first_name"] = "firstname"; + my_id.erase("username"); + my_authenticator.erase("creds"); + my_authenticator["hash"] = "6563245"; + + my_cred->setCredentialData(my_id, my_authenticator); + ensure_equals("set credential data: identifier", my_id, my_cred->getIdentifier()); + ensure_equals("set credential data: authenticator", my_authenticator, my_cred->getAuthenticator()); + ensure_equals("set credential data: grid", "my_grid", my_cred->getGrid()); + + // test loading of a credential, that hasn't been saved, without + // any legacy saved credential data + LLPointer<LLCredential> my_new_cred = handler->loadCredential("my_grid2"); + ensure("unknown credential load test", my_new_cred->getIdentifier().isMap()); + ensure("unknown credential load test", !my_new_cred->getIdentifier().has("type")); + ensure("unknown credential load test", my_new_cred->getAuthenticator().isMap()); + ensure("unknown credential load test", !my_new_cred->getAuthenticator().has("type")); + // test saving of a credential + handler->saveCredential(my_cred, true); + + // test loading of a known credential + my_new_cred = handler->loadCredential("my_grid"); + ensure_equals("load a known credential: identifier", my_id, my_new_cred->getIdentifier()); + ensure_equals("load a known credential: authenticator",my_authenticator, my_new_cred->getAuthenticator()); + ensure_equals("load a known credential: grid", "my_grid", my_cred->getGrid()); + + // test deletion of a credential + handler->deleteCredential(my_new_cred); + + ensure("delete credential: identifier", my_new_cred->getIdentifier().isUndefined()); + ensure("delete credentialt: authenticator", my_new_cred->getIdentifier().isUndefined()); + ensure_equals("delete credential: grid", "my_grid", my_cred->getGrid()); + // load unknown cred + + my_new_cred = handler->loadCredential("my_grid"); + ensure("deleted credential load test", my_new_cred->getIdentifier().isMap()); + ensure("deleted credential load test", !my_new_cred->getIdentifier().has("type")); + ensure("deleted credential load test", my_new_cred->getAuthenticator().isMap()); + ensure("deleted credential load test", !my_new_cred->getAuthenticator().has("type")); + + // test loading of an unknown credential with legacy saved username, but without + // saved password + gFirstName = "myfirstname"; + gLastName = "mylastname"; + my_new_cred = handler->loadCredential("my_legacy_grid"); + ensure_equals("legacy credential with no password: type", + (const std::string)my_new_cred->getIdentifier()["type"], "agent"); + ensure_equals("legacy credential with no password: first_name", + (const std::string)my_new_cred->getIdentifier()["first_name"], "myfirstname"); + ensure_equals("legacy credential with no password: last_name", + (const std::string)my_new_cred->getIdentifier()["last_name"], "mylastname"); + + ensure("legacy credential with no password: no authenticator", my_new_cred->getAuthenticator().isUndefined()); + + // test loading of an unknown credential with legacy saved password and username + + std::string hashed_password = "fSQcLG03eyIWJmkzfyYaKm81dSweLmsxeSAYKGE7fSQ="; + int length = apr_base64_decode_len(hashed_password.c_str()); + std::vector<char> decoded_password(length); + apr_base64_decode(&decoded_password[0], hashed_password.c_str()); + LLXORCipher cipher(gMACAddress, MAC_ADDRESS_BYTES); + cipher.decrypt((U8*)&decoded_password[0], length); + unsigned char unique_id[MAC_ADDRESS_BYTES]; + LLMachineID::getUniqueID(unique_id, sizeof(unique_id)); + LLXORCipher cipher2(unique_id, sizeof(unique_id)); + cipher2.encrypt((U8*)&decoded_password[0], length); + llofstream password_file("test_password.dat", std::ofstream::binary); + password_file.write(&decoded_password[0], length); + password_file.close(); + + my_new_cred = handler->loadCredential("my_legacy_grid2"); + ensure_equals("legacy credential with password: type", + (const std::string)my_new_cred->getIdentifier()["type"], "agent"); + ensure_equals("legacy credential with password: first_name", + (const std::string)my_new_cred->getIdentifier()["first_name"], "myfirstname"); + ensure_equals("legacy credential with password: last_name", + (const std::string)my_new_cred->getIdentifier()["last_name"], "mylastname"); + + LLSD legacy_authenticator = my_new_cred->getAuthenticator(); + ensure_equals("legacy credential with password: type", + (std::string)legacy_authenticator["type"], + "hash"); + ensure_equals("legacy credential with password: algorithm", + (std::string)legacy_authenticator["algorithm"], + "md5"); + ensure_equals("legacy credential with password: algorithm", + (std::string)legacy_authenticator["secret"], + "01234567890123456789012345678901"); + + // test creation of credentials + my_cred = handler->createCredential("mysavedgrid", my_id, my_authenticator); + // test save without saving authenticator. + handler->saveCredential(my_cred, FALSE); + my_new_cred = handler->loadCredential("mysavedgrid"); + ensure_equals("saved credential without auth", + (const std::string)my_new_cred->getIdentifier()["type"], "test_type"); + ensure("no authenticator values were saved", my_new_cred->getAuthenticator().isUndefined()); + } + + // test cert vector + template<> template<> + void sechandler_basic_test_object::test<4>() + { + + // validate create from empty vector + LLPointer<LLBasicCertificateVector> test_vector = new LLBasicCertificateVector(); + ensure_equals("when loading with nothing, we should result in no certs in vector", test_vector->size(), 0); + + test_vector->add(new LLBasicCertificate(mPemTestCert)); + ensure_equals("one element in vector", test_vector->size(), 1); + test_vector->add(new LLBasicCertificate(mPemChildCert)); + ensure_equals("two elements in vector after add", test_vector->size(), 2); + + test_vector->add(new LLBasicCertificate(mPemChildCert)); + ensure_equals("two elements in vector after re-add", test_vector->size(), 2); + // validate order + X509* test_cert = (*test_vector)[0]->getOpenSSLX509(); + ensure("first cert added remains first cert", !X509_cmp(test_cert, mX509TestCert)); + X509_free(test_cert); + + test_cert = (*test_vector)[1]->getOpenSSLX509(); + ensure("adding a duplicate cert", !X509_cmp(test_cert, mX509ChildCert)); + X509_free(test_cert); + + // + // validate iterator + // + LLBasicCertificateVector::iterator current_cert = test_vector->begin(); + LLBasicCertificateVector::iterator copy_current_cert = current_cert; + // operator++(int) + ensure("validate iterator++ element in vector is expected cert", *current_cert++ == (*test_vector)[0]); + ensure("validate 2nd iterator++ element in vector is expected cert", *current_cert++ == (*test_vector)[1]); + ensure("validate end iterator++", current_cert == test_vector->end()); + + // copy + ensure("validate copy iterator element in vector is expected cert", *copy_current_cert == (*test_vector)[0]); + + // operator--(int) + current_cert--; + ensure("validate iterator-- element in vector is expected cert", *current_cert-- == (*test_vector)[1]); + ensure("validate iterator-- element in vector is expected cert", *current_cert == (*test_vector)[0]); + + ensure("begin iterator is equal", current_cert == test_vector->begin()); + + // operator++ + ensure("validate ++iterator element in vector is expected cert", *++current_cert == (*test_vector)[1]); + ensure("end of cert vector after ++iterator", ++current_cert == test_vector->end()); + // operator-- + ensure("validate --iterator element in vector is expected cert", *--current_cert == (*test_vector)[1]); + ensure("validate 2nd --iterator element in vector is expected cert", *--current_cert == (*test_vector)[0]); + + // validate remove + // validate create from empty vector + test_vector = new LLBasicCertificateVector(); + test_vector->add(new LLBasicCertificate(mPemTestCert)); + test_vector->add(new LLBasicCertificate(mPemChildCert)); + test_vector->erase(test_vector->begin()); + ensure_equals("one element in store after remove", test_vector->size(), 1); + test_cert = (*test_vector)[0]->getOpenSSLX509(); + ensure("validate cert was removed", !X509_cmp(test_cert, mX509ChildCert)); + X509_free(test_cert); + + // validate insert + test_vector->insert(test_vector->begin(), new LLBasicCertificate(mPemChildCert)); + test_cert = (*test_vector)[0]->getOpenSSLX509(); + + ensure("validate cert was inserted", !X509_cmp(test_cert, mX509ChildCert)); + X509_free(test_cert); + + //validate find + LLSD find_info = LLSD::emptyMap(); + test_vector->insert(test_vector->begin(), new LLBasicCertificate(mPemRootCert)); + find_info["issuer_name"] = LLSD::emptyMap(); + find_info["issuer_name"]["commonName"] = "Roxies intermediate CA"; + find_info["md5_digest"] = "97:24:c7:4c:d4:ba:2d:0e:9c:a1:18:8e:3a:c6:1f:c3"; + current_cert = test_vector->find(find_info); + ensure("found", current_cert != test_vector->end()); + ensure("found cert", (*current_cert).get() == (*test_vector)[1].get()); + find_info["sha1_digest"] = "bad value"; + current_cert =test_vector->find(find_info); + ensure("didn't find cert", current_cert == test_vector->end()); + } + + // test cert store + template<> template<> + void sechandler_basic_test_object::test<5>() + { + // validate load with nothing + LLFile::remove("mycertstore.pem"); + LLPointer<LLBasicCertificateStore> test_store = new LLBasicCertificateStore("mycertstore.pem"); + ensure_equals("when loading with nothing, we should result in no certs in store", test_store->size(), 0); + + // validate load with empty file + test_store->save(); + test_store = NULL; + test_store = new LLBasicCertificateStore("mycertstore.pem"); + ensure_equals("when loading with nothing, we should result in no certs in store", test_store->size(), 0); + test_store=NULL; + + // instantiate a cert store from a file + llofstream certstorefile("mycertstore.pem", std::ios::out); + certstorefile << mPemChildCert << std::endl << mPemTestCert << std::endl; + certstorefile.close(); + // validate loaded certs + test_store = new LLBasicCertificateStore("mycertstore.pem"); + ensure_equals("two elements in store", test_store->size(), 2); + + // operator[] + X509* test_cert = (*test_store)[0]->getOpenSSLX509(); + + ensure("validate first element in store is expected cert", !X509_cmp(test_cert, mX509ChildCert)); + X509_free(test_cert); + test_cert = (*test_store)[1]->getOpenSSLX509(); + ensure("validate second element in store is expected cert", !X509_cmp(test_cert, mX509TestCert)); + X509_free(test_cert); + + + // validate save + LLFile::remove("mycertstore.pem"); + test_store->save(); + test_store = NULL; + test_store = new LLBasicCertificateStore("mycertstore.pem"); + ensure_equals("two elements in store after save", test_store->size(), 2); + LLCertificateStore::iterator current_cert = test_store->begin(); + test_cert = (*current_cert)->getOpenSSLX509(); + ensure("validate first element in store is expected cert", !X509_cmp(test_cert, mX509ChildCert)); + current_cert++; + X509_free(test_cert); + test_cert = (*current_cert)->getOpenSSLX509(); + ensure("validate second element in store is expected cert", !X509_cmp(test_cert, mX509TestCert)); + X509_free(test_cert); + current_cert++; + ensure("end of cert store", current_cert == test_store->end()); + + } + + // cert name wildcard matching + template<> template<> + void sechandler_basic_test_object::test<6>() + { + ensure("simple name match", + _cert_hostname_wildcard_match("foo", "foo")); + + ensure("simple name match, with end period", + _cert_hostname_wildcard_match("foo.", "foo.")); + + ensure("simple name match, with begin period", + _cert_hostname_wildcard_match(".foo", ".foo")); + + ensure("simple name match, with mismatched period cn", + _cert_hostname_wildcard_match("foo.", "foo")); + + ensure("simple name match, with mismatched period hostname", + _cert_hostname_wildcard_match("foo", "foo.")); + + ensure("simple name match, with subdomain", + _cert_hostname_wildcard_match("foo.bar", "foo.bar")); + + ensure("stutter name match", + _cert_hostname_wildcard_match("foobbbbfoo", "foo*bbbfoo")); + + ensure("simple name match, with beginning wildcard", + _cert_hostname_wildcard_match("foobar", "*bar")); + + ensure("simple name match, with ending wildcard", + _cert_hostname_wildcard_match("foobar", "foo*")); + + ensure("simple name match, with beginning null wildcard", + _cert_hostname_wildcard_match("foobar", "*foobar")); + + ensure("simple name match, with ending null wildcard", + _cert_hostname_wildcard_match("foobar", "foobar*")); + + ensure("simple name match, with embedded wildcard", + _cert_hostname_wildcard_match("foobar", "f*r")); + + ensure("simple name match, with embedded null wildcard", + _cert_hostname_wildcard_match("foobar", "foo*bar")); + + ensure("simple name match, with dual embedded wildcard", + _cert_hostname_wildcard_match("foobar", "f*o*ar")); + + ensure("simple name mismatch", + !_cert_hostname_wildcard_match("bar", "foo")); + + ensure("simple name mismatch, with end period", + !_cert_hostname_wildcard_match("foobar.", "foo.")); + + ensure("simple name mismatch, with begin period", + !_cert_hostname_wildcard_match(".foobar", ".foo")); + + ensure("simple name mismatch, with subdomain", + !_cert_hostname_wildcard_match("foobar.bar", "foo.bar")); + + ensure("simple name mismatch, with beginning wildcard", + !_cert_hostname_wildcard_match("foobara", "*bar")); + + ensure("simple name mismatch, with ending wildcard", + !_cert_hostname_wildcard_match("oobar", "foo*")); + + ensure("simple name mismatch, with embedded wildcard", + !_cert_hostname_wildcard_match("oobar", "f*r")); + + ensure("simple name mismatch, with dual embedded wildcard", + !_cert_hostname_wildcard_match("foobar", "f*d*ar")); + + ensure("simple wildcard", + _cert_hostname_wildcard_match("foobar", "*")); + + ensure("long domain", + _cert_hostname_wildcard_match("foo.bar.com", "foo.bar.com")); + + ensure("long domain with multiple wildcards", + _cert_hostname_wildcard_match("foo.bar.com", "*.b*r.com")); + + ensure("end periods", + _cert_hostname_wildcard_match("foo.bar.com.", "*.b*r.com.")); + + ensure("match end period", + _cert_hostname_wildcard_match("foo.bar.com.", "*.b*r.com")); + + ensure("match end period2", + _cert_hostname_wildcard_match("foo.bar.com", "*.b*r.com.")); + + ensure("wildcard mismatch", + !_cert_hostname_wildcard_match("bar.com", "*.bar.com")); + + ensure("wildcard match", + _cert_hostname_wildcard_match("foo.bar.com", "*.bar.com")); + + ensure("wildcard match", + _cert_hostname_wildcard_match("foo.foo.bar.com", "*.bar.com")); + + ensure("wildcard match", + _cert_hostname_wildcard_match("foo.foo.bar.com", "*.*.com")); + + ensure("wildcard mismatch", + !_cert_hostname_wildcard_match("foo.foo.bar.com", "*.foo.com")); + } + + // test cert chain + template<> template<> + void sechandler_basic_test_object::test<7>() + { + // validate create from empty chain + LLPointer<LLBasicCertificateChain> test_chain = new LLBasicCertificateChain(NULL); + ensure_equals("when loading with nothing, we should result in no certs in chain", test_chain->size(), 0); + + // Single cert in the chain. + X509_STORE_CTX *test_store = X509_STORE_CTX_new(); + test_store->cert = mX509ChildCert; + test_store->untrusted = NULL; + test_chain = new LLBasicCertificateChain(test_store); + X509_STORE_CTX_free(test_store); + ensure_equals("two elements in store", test_chain->size(), 1); + X509* test_cert = (*test_chain)[0]->getOpenSSLX509(); + ensure("validate first element in store is expected cert", !X509_cmp(test_cert, mX509ChildCert)); + X509_free(test_cert); + + // cert + CA + + test_store = X509_STORE_CTX_new(); + test_store->cert = mX509ChildCert; + test_store->untrusted = sk_X509_new_null(); + sk_X509_push(test_store->untrusted, mX509IntermediateCert); + test_chain = new LLBasicCertificateChain(test_store); + X509_STORE_CTX_free(test_store); + ensure_equals("two elements in store", test_chain->size(), 2); + test_cert = (*test_chain)[0]->getOpenSSLX509(); + ensure("validate first element in store is expected cert", !X509_cmp(test_cert, mX509ChildCert)); + X509_free(test_cert); + test_cert = (*test_chain)[1]->getOpenSSLX509(); + ensure("validate second element in store is expected cert", !X509_cmp(test_cert, mX509IntermediateCert)); + X509_free(test_cert); + + // cert + nonrelated + + test_store = X509_STORE_CTX_new(); + test_store->cert = mX509ChildCert; + test_store->untrusted = sk_X509_new_null(); + sk_X509_push(test_store->untrusted, mX509TestCert); + test_chain = new LLBasicCertificateChain(test_store); + X509_STORE_CTX_free(test_store); + ensure_equals("two elements in store", test_chain->size(), 1); + test_cert = (*test_chain)[0]->getOpenSSLX509(); + ensure("validate first element in store is expected cert", !X509_cmp(test_cert, mX509ChildCert)); + X509_free(test_cert); + + // cert + CA + nonrelated + test_store = X509_STORE_CTX_new(); + test_store->cert = mX509ChildCert; + test_store->untrusted = sk_X509_new_null(); + sk_X509_push(test_store->untrusted, mX509IntermediateCert); + sk_X509_push(test_store->untrusted, mX509TestCert); + test_chain = new LLBasicCertificateChain(test_store); + X509_STORE_CTX_free(test_store); + ensure_equals("two elements in store", test_chain->size(), 2); + test_cert = (*test_chain)[0]->getOpenSSLX509(); + ensure("validate first element in store is expected cert", !X509_cmp(test_cert, mX509ChildCert)); + X509_free(test_cert); + test_cert = (*test_chain)[1]->getOpenSSLX509(); + ensure("validate second element in store is expected cert", !X509_cmp(test_cert, mX509IntermediateCert)); + X509_free(test_cert); + + // cert + intermediate + CA + test_store = X509_STORE_CTX_new(); + test_store->cert = mX509ChildCert; + test_store->untrusted = sk_X509_new_null(); + sk_X509_push(test_store->untrusted, mX509IntermediateCert); + sk_X509_push(test_store->untrusted, mX509RootCert); + test_chain = new LLBasicCertificateChain(test_store); + X509_STORE_CTX_free(test_store); + ensure_equals("three elements in store", test_chain->size(), 3); + test_cert = (*test_chain)[0]->getOpenSSLX509(); + ensure("validate first element in store is expected cert", !X509_cmp(test_cert, mX509ChildCert)); + X509_free(test_cert); + test_cert = (*test_chain)[1]->getOpenSSLX509(); + ensure("validate second element in store is expected cert", !X509_cmp(test_cert, mX509IntermediateCert)); + X509_free(test_cert); + + test_cert = (*test_chain)[2]->getOpenSSLX509(); + ensure("validate second element in store is expected cert", !X509_cmp(test_cert, mX509RootCert)); + X509_free(test_cert); + } + // test cert validation + template<> template<> + void sechandler_basic_test_object::test<8>() + { + // start with a trusted store with our known root cert + LLFile::remove("mycertstore.pem"); + LLPointer<LLBasicCertificateStore> test_store = new LLBasicCertificateStore("mycertstore.pem"); + test_store->add(new LLBasicCertificate(mX509RootCert)); + LLSD validation_params; + + // validate basic trust for a chain containing only the intermediate cert. (1 deep) + LLPointer<LLBasicCertificateChain> test_chain = new LLBasicCertificateChain(NULL); + + test_chain->add(new LLBasicCertificate(mX509IntermediateCert)); + + test_store->validate(0, test_chain, validation_params); + + // add the root certificate to the chain and revalidate + test_chain->add(new LLBasicCertificate(mX509RootCert)); + test_store->validate(0, test_chain, validation_params); + + // add the child cert at the head of the chain, and revalidate (3 deep chain) + test_chain->insert(test_chain->begin(), new LLBasicCertificate(mX509ChildCert)); + test_store->validate(0, test_chain, validation_params); + + // basic failure cases + test_chain = new LLBasicCertificateChain(NULL); + //validate with only the child cert in chain, but child cert was previously + // trusted + test_chain->add(new LLBasicCertificate(mX509ChildCert)); + + // validate without the trust flag. + test_store->validate(VALIDATION_POLICY_TRUSTED, test_chain, validation_params); + + // Validate with child cert but no parent, and no parent in CA store + test_store = new LLBasicCertificateStore("mycertstore.pem"); + ensure_throws("no CA, with only a child cert", + LLCertValidationTrustException, + (*test_chain)[0], + test_store->validate, + VALIDATION_POLICY_TRUSTED, + test_chain, + validation_params); + + + // validate without the trust flag. + test_store->validate(0, test_chain, validation_params); + + // clear out the store + test_store = new LLBasicCertificateStore("mycertstore.pem"); + // append the intermediate cert + test_chain->add(new LLBasicCertificate(mX509IntermediateCert)); + ensure_throws("no CA, with child and intermediate certs", + LLCertValidationTrustException, + (*test_chain)[1], + test_store->validate, + VALIDATION_POLICY_TRUSTED, + test_chain, + validation_params); + // validate without the trust flag + test_store->validate(0, test_chain, validation_params); + + // Test time validity + LLSD child_info; + ((*test_chain)[0])->getLLSD(child_info); + validation_params = LLSD::emptyMap(); + validation_params[CERT_VALIDATION_DATE] = LLDate(child_info[CERT_VALID_FROM].asDate().secondsSinceEpoch() + 1.0); + test_store->validate(VALIDATION_POLICY_TIME, test_chain, validation_params); + + validation_params = LLSD::emptyMap(); + validation_params[CERT_VALIDATION_DATE] = child_info[CERT_VALID_FROM].asDate(); + + validation_params[CERT_VALIDATION_DATE] = LLDate(child_info[CERT_VALID_FROM].asDate().secondsSinceEpoch() - 1.0); + + // test not yet valid + ensure_throws("Child cert not yet valid" , + LLCertValidationExpirationException, + (*test_chain)[0], + test_store->validate, + VALIDATION_POLICY_TIME, + test_chain, + validation_params); + validation_params = LLSD::emptyMap(); + validation_params[CERT_VALIDATION_DATE] = LLDate(child_info[CERT_VALID_TO].asDate().secondsSinceEpoch() + 1.0); + + // test cert expired + ensure_throws("Child cert expired", + LLCertValidationExpirationException, + (*test_chain)[0], + test_store->validate, + VALIDATION_POLICY_TIME, + test_chain, + validation_params); + + // test SSL KU + // validate basic trust for a chain containing child and intermediate. + test_chain = new LLBasicCertificateChain(NULL); + test_chain->add(new LLBasicCertificate(mX509ChildCert)); + test_chain->add(new LLBasicCertificate(mX509IntermediateCert)); + test_store->validate(VALIDATION_POLICY_SSL_KU, test_chain, validation_params); + + test_chain = new LLBasicCertificateChain(NULL); + test_chain->add(new LLBasicCertificate(mX509TestCert)); + + test_store = new LLBasicCertificateStore("mycertstore.pem"); + ensure_throws("Cert doesn't have ku", + LLCertKeyUsageValidationException, + (*test_chain)[0], + test_store->validate, + VALIDATION_POLICY_SSL_KU, + test_chain, + validation_params); + + // test sha1RSA validation + test_chain = new LLBasicCertificateChain(NULL); + test_chain->add(new LLBasicCertificate(mSha1RSATestCert)); + test_chain->add(new LLBasicCertificate(mSha1RSATestCA)); + + test_store->validate(0, test_chain, validation_params); + } + +}; + diff --git a/indra/newview/tests/llsimplestat_test.cpp b/indra/newview/tests/llsimplestat_test.cpp new file mode 100644 index 0000000000..b556941f4a --- /dev/null +++ b/indra/newview/tests/llsimplestat_test.cpp @@ -0,0 +1,580 @@ +/** + * @file llsimplestats_test.cpp + * @date 2010-10-22 + * @brief Test cases for some of llsimplestat.h + * + * $LicenseInfo:firstyear=2010&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "linden_common.h" + +#include <tut/tut.hpp> + +#include "lltut.h" +#include "../llsimplestat.h" +#include "llsd.h" +#include "llmath.h" + +// @brief Used as a pointer cast type to get access to LLSimpleStatCounter +class TutStatCounter: public LLSimpleStatCounter +{ +public: + TutStatCounter(); // Not defined + ~TutStatCounter(); // Not defined + void operator=(const TutStatCounter &); // Not defined + + void setRawCount(U32 c) { mCount = c; } + U32 getRawCount() const { return mCount; } +}; + + +namespace tut +{ + struct stat_counter_index + {}; + typedef test_group<stat_counter_index> stat_counter_index_t; + typedef stat_counter_index_t::object stat_counter_index_object_t; + tut::stat_counter_index_t tut_stat_counter_index("stat_counter_test"); + + // Testing LLSimpleStatCounter's external interface + template<> template<> + void stat_counter_index_object_t::test<1>() + { + LLSimpleStatCounter c1; + ensure("Initialized counter is zero", (0 == c1.getCount())); + + ensure("Counter increment return is 1", (1 == ++c1)); + ensure("Counter increment return is 2", (2 == ++c1)); + + ensure("Current counter is 2", (2 == c1.getCount())); + + c1.reset(); + ensure("Counter is 0 after reset", (0 == c1.getCount())); + + ensure("Counter increment return is 1", (1 == ++c1)); + } + + // Testing LLSimpleStatCounter's internal state + template<> template<> + void stat_counter_index_object_t::test<2>() + { + LLSimpleStatCounter c1; + TutStatCounter * tc1 = (TutStatCounter *) &c1; + + ensure("Initialized private counter is zero", (0 == tc1->getRawCount())); + + ++c1; + ++c1; + + ensure("Current private counter is 2", (2 == tc1->getRawCount())); + + c1.reset(); + ensure("Raw counter is 0 after reset", (0 == tc1->getRawCount())); + } + + // Testing LLSimpleStatCounter's wrapping behavior + template<> template<> + void stat_counter_index_object_t::test<3>() + { + LLSimpleStatCounter c1; + TutStatCounter * tc1 = (TutStatCounter *) &c1; + + tc1->setRawCount(U32_MAX); + ensure("Initialized private counter is zero", (U32_MAX == c1.getCount())); + + ensure("Increment of max value wraps to 0", (0 == ++c1)); + } + + // Testing LLSimpleStatMMM's external behavior + template<> template<> + void stat_counter_index_object_t::test<4>() + { + LLSimpleStatMMM<> m1; + typedef LLSimpleStatMMM<>::Value lcl_float; + lcl_float zero(0); + + // Freshly-constructed + ensure("Constructed MMM<> has 0 count", (0 == m1.getCount())); + ensure("Constructed MMM<> has 0 min", (zero == m1.getMin())); + ensure("Constructed MMM<> has 0 max", (zero == m1.getMax())); + ensure("Constructed MMM<> has 0 mean no div-by-zero", (zero == m1.getMean())); + + // Single insert + m1.record(1.0); + ensure("Single insert MMM<> has 1 count", (1 == m1.getCount())); + ensure("Single insert MMM<> has 1.0 min", (1.0 == m1.getMin())); + ensure("Single insert MMM<> has 1.0 max", (1.0 == m1.getMax())); + ensure("Single insert MMM<> has 1.0 mean", (1.0 == m1.getMean())); + + // Second insert + m1.record(3.0); + ensure("2nd insert MMM<> has 2 count", (2 == m1.getCount())); + ensure("2nd insert MMM<> has 1.0 min", (1.0 == m1.getMin())); + ensure("2nd insert MMM<> has 3.0 max", (3.0 == m1.getMax())); + ensure_approximately_equals("2nd insert MMM<> has 2.0 mean", m1.getMean(), lcl_float(2.0), 1); + + // Third insert + m1.record(5.0); + ensure("3rd insert MMM<> has 3 count", (3 == m1.getCount())); + ensure("3rd insert MMM<> has 1.0 min", (1.0 == m1.getMin())); + ensure("3rd insert MMM<> has 5.0 max", (5.0 == m1.getMax())); + ensure_approximately_equals("3rd insert MMM<> has 3.0 mean", m1.getMean(), lcl_float(3.0), 1); + + // Fourth insert + m1.record(1000000.0); + ensure("4th insert MMM<> has 4 count", (4 == m1.getCount())); + ensure("4th insert MMM<> has 1.0 min", (1.0 == m1.getMin())); + ensure("4th insert MMM<> has 100000.0 max", (1000000.0 == m1.getMax())); + ensure_approximately_equals("4th insert MMM<> has 250002.0 mean", m1.getMean(), lcl_float(250002.0), 1); + + // Reset + m1.reset(); + ensure("Reset MMM<> has 0 count", (0 == m1.getCount())); + ensure("Reset MMM<> has 0 min", (zero == m1.getMin())); + ensure("Reset MMM<> has 0 max", (zero == m1.getMax())); + ensure("Reset MMM<> has 0 mean no div-by-zero", (zero == m1.getMean())); + } + + // Testing LLSimpleStatMMM's response to large values + template<> template<> + void stat_counter_index_object_t::test<5>() + { + LLSimpleStatMMM<> m1; + typedef LLSimpleStatMMM<>::Value lcl_float; + lcl_float zero(0); + + // Insert overflowing values + const lcl_float bignum(F32_MAX / 2); + + m1.record(bignum); + m1.record(bignum); + m1.record(bignum); + m1.record(bignum); + m1.record(bignum); + m1.record(bignum); + m1.record(bignum); + m1.record(zero); + + ensure("Overflowed MMM<> has 8 count", (8 == m1.getCount())); + ensure("Overflowed MMM<> has 0 min", (zero == m1.getMin())); + ensure("Overflowed MMM<> has huge max", (bignum == m1.getMax())); + ensure("Overflowed MMM<> has fetchable mean", (1.0 == m1.getMean() || true)); + // We should be infinte but not interested in proving the IEEE standard here. + LLSD sd1(m1.getMean()); + // std::cout << "Thingy: " << m1.getMean() << " and as LLSD: " << sd1 << std::endl; + ensure("Overflowed MMM<> produces LLSDable Real", (sd1.isReal())); + } + + // Testing LLSimpleStatMMM<F32>'s external behavior + template<> template<> + void stat_counter_index_object_t::test<6>() + { + LLSimpleStatMMM<F32> m1; + typedef LLSimpleStatMMM<F32>::Value lcl_float; + lcl_float zero(0); + + // Freshly-constructed + ensure("Constructed MMM<F32> has 0 count", (0 == m1.getCount())); + ensure("Constructed MMM<F32> has 0 min", (zero == m1.getMin())); + ensure("Constructed MMM<F32> has 0 max", (zero == m1.getMax())); + ensure("Constructed MMM<F32> has 0 mean no div-by-zero", (zero == m1.getMean())); + + // Single insert + m1.record(1.0); + ensure("Single insert MMM<F32> has 1 count", (1 == m1.getCount())); + ensure("Single insert MMM<F32> has 1.0 min", (1.0 == m1.getMin())); + ensure("Single insert MMM<F32> has 1.0 max", (1.0 == m1.getMax())); + ensure("Single insert MMM<F32> has 1.0 mean", (1.0 == m1.getMean())); + + // Second insert + m1.record(3.0); + ensure("2nd insert MMM<F32> has 2 count", (2 == m1.getCount())); + ensure("2nd insert MMM<F32> has 1.0 min", (1.0 == m1.getMin())); + ensure("2nd insert MMM<F32> has 3.0 max", (3.0 == m1.getMax())); + ensure_approximately_equals("2nd insert MMM<F32> has 2.0 mean", m1.getMean(), lcl_float(2.0), 1); + + // Third insert + m1.record(5.0); + ensure("3rd insert MMM<F32> has 3 count", (3 == m1.getCount())); + ensure("3rd insert MMM<F32> has 1.0 min", (1.0 == m1.getMin())); + ensure("3rd insert MMM<F32> has 5.0 max", (5.0 == m1.getMax())); + ensure_approximately_equals("3rd insert MMM<F32> has 3.0 mean", m1.getMean(), lcl_float(3.0), 1); + + // Fourth insert + m1.record(1000000.0); + ensure("4th insert MMM<F32> has 4 count", (4 == m1.getCount())); + ensure("4th insert MMM<F32> has 1.0 min", (1.0 == m1.getMin())); + ensure("4th insert MMM<F32> has 1000000.0 max", (1000000.0 == m1.getMax())); + ensure_approximately_equals("4th insert MMM<F32> has 250002.0 mean", m1.getMean(), lcl_float(250002.0), 1); + + // Reset + m1.reset(); + ensure("Reset MMM<F32> has 0 count", (0 == m1.getCount())); + ensure("Reset MMM<F32> has 0 min", (zero == m1.getMin())); + ensure("Reset MMM<F32> has 0 max", (zero == m1.getMax())); + ensure("Reset MMM<F32> has 0 mean no div-by-zero", (zero == m1.getMean())); + } + + // Testing LLSimpleStatMMM's response to large values + template<> template<> + void stat_counter_index_object_t::test<7>() + { + LLSimpleStatMMM<F32> m1; + typedef LLSimpleStatMMM<F32>::Value lcl_float; + lcl_float zero(0); + + // Insert overflowing values + const lcl_float bignum(F32_MAX / 2); + + m1.record(bignum); + m1.record(bignum); + m1.record(bignum); + m1.record(bignum); + m1.record(bignum); + m1.record(bignum); + m1.record(bignum); + m1.record(zero); + + ensure("Overflowed MMM<F32> has 8 count", (8 == m1.getCount())); + ensure("Overflowed MMM<F32> has 0 min", (zero == m1.getMin())); + ensure("Overflowed MMM<F32> has huge max", (bignum == m1.getMax())); + ensure("Overflowed MMM<F32> has fetchable mean", (1.0 == m1.getMean() || true)); + // We should be infinte but not interested in proving the IEEE standard here. + LLSD sd1(m1.getMean()); + // std::cout << "Thingy: " << m1.getMean() << " and as LLSD: " << sd1 << std::endl; + ensure("Overflowed MMM<F32> produces LLSDable Real", (sd1.isReal())); + } + + // Testing LLSimpleStatMMM<F64>'s external behavior + template<> template<> + void stat_counter_index_object_t::test<8>() + { + LLSimpleStatMMM<F64> m1; + typedef LLSimpleStatMMM<F64>::Value lcl_float; + lcl_float zero(0); + + // Freshly-constructed + ensure("Constructed MMM<F64> has 0 count", (0 == m1.getCount())); + ensure("Constructed MMM<F64> has 0 min", (zero == m1.getMin())); + ensure("Constructed MMM<F64> has 0 max", (zero == m1.getMax())); + ensure("Constructed MMM<F64> has 0 mean no div-by-zero", (zero == m1.getMean())); + + // Single insert + m1.record(1.0); + ensure("Single insert MMM<F64> has 1 count", (1 == m1.getCount())); + ensure("Single insert MMM<F64> has 1.0 min", (1.0 == m1.getMin())); + ensure("Single insert MMM<F64> has 1.0 max", (1.0 == m1.getMax())); + ensure("Single insert MMM<F64> has 1.0 mean", (1.0 == m1.getMean())); + + // Second insert + m1.record(3.0); + ensure("2nd insert MMM<F64> has 2 count", (2 == m1.getCount())); + ensure("2nd insert MMM<F64> has 1.0 min", (1.0 == m1.getMin())); + ensure("2nd insert MMM<F64> has 3.0 max", (3.0 == m1.getMax())); + ensure_approximately_equals("2nd insert MMM<F64> has 2.0 mean", m1.getMean(), lcl_float(2.0), 1); + + // Third insert + m1.record(5.0); + ensure("3rd insert MMM<F64> has 3 count", (3 == m1.getCount())); + ensure("3rd insert MMM<F64> has 1.0 min", (1.0 == m1.getMin())); + ensure("3rd insert MMM<F64> has 5.0 max", (5.0 == m1.getMax())); + ensure_approximately_equals("3rd insert MMM<F64> has 3.0 mean", m1.getMean(), lcl_float(3.0), 1); + + // Fourth insert + m1.record(1000000.0); + ensure("4th insert MMM<F64> has 4 count", (4 == m1.getCount())); + ensure("4th insert MMM<F64> has 1.0 min", (1.0 == m1.getMin())); + ensure("4th insert MMM<F64> has 1000000.0 max", (1000000.0 == m1.getMax())); + ensure_approximately_equals("4th insert MMM<F64> has 250002.0 mean", m1.getMean(), lcl_float(250002.0), 1); + + // Reset + m1.reset(); + ensure("Reset MMM<F64> has 0 count", (0 == m1.getCount())); + ensure("Reset MMM<F64> has 0 min", (zero == m1.getMin())); + ensure("Reset MMM<F64> has 0 max", (zero == m1.getMax())); + ensure("Reset MMM<F64> has 0 mean no div-by-zero", (zero == m1.getMean())); + } + + // Testing LLSimpleStatMMM's response to large values + template<> template<> + void stat_counter_index_object_t::test<9>() + { + LLSimpleStatMMM<F64> m1; + typedef LLSimpleStatMMM<F64>::Value lcl_float; + lcl_float zero(0); + + // Insert overflowing values + const lcl_float bignum(F64_MAX / 2); + + m1.record(bignum); + m1.record(bignum); + m1.record(bignum); + m1.record(bignum); + m1.record(bignum); + m1.record(bignum); + m1.record(bignum); + m1.record(zero); + + ensure("Overflowed MMM<F64> has 8 count", (8 == m1.getCount())); + ensure("Overflowed MMM<F64> has 0 min", (zero == m1.getMin())); + ensure("Overflowed MMM<F64> has huge max", (bignum == m1.getMax())); + ensure("Overflowed MMM<F64> has fetchable mean", (1.0 == m1.getMean() || true)); + // We should be infinte but not interested in proving the IEEE standard here. + LLSD sd1(m1.getMean()); + // std::cout << "Thingy: " << m1.getMean() << " and as LLSD: " << sd1 << std::endl; + ensure("Overflowed MMM<F64> produces LLSDable Real", (sd1.isReal())); + } + + // Testing LLSimpleStatMMM<U64>'s external behavior + template<> template<> + void stat_counter_index_object_t::test<10>() + { + LLSimpleStatMMM<U64> m1; + typedef LLSimpleStatMMM<U64>::Value lcl_int; + lcl_int zero(0); + + // Freshly-constructed + ensure("Constructed MMM<U64> has 0 count", (0 == m1.getCount())); + ensure("Constructed MMM<U64> has 0 min", (zero == m1.getMin())); + ensure("Constructed MMM<U64> has 0 max", (zero == m1.getMax())); + ensure("Constructed MMM<U64> has 0 mean no div-by-zero", (zero == m1.getMean())); + + // Single insert + m1.record(1); + ensure("Single insert MMM<U64> has 1 count", (1 == m1.getCount())); + ensure("Single insert MMM<U64> has 1 min", (1 == m1.getMin())); + ensure("Single insert MMM<U64> has 1 max", (1 == m1.getMax())); + ensure("Single insert MMM<U64> has 1 mean", (1 == m1.getMean())); + + // Second insert + m1.record(3); + ensure("2nd insert MMM<U64> has 2 count", (2 == m1.getCount())); + ensure("2nd insert MMM<U64> has 1 min", (1 == m1.getMin())); + ensure("2nd insert MMM<U64> has 3 max", (3 == m1.getMax())); + ensure("2nd insert MMM<U64> has 2 mean", (2 == m1.getMean())); + + // Third insert + m1.record(5); + ensure("3rd insert MMM<U64> has 3 count", (3 == m1.getCount())); + ensure("3rd insert MMM<U64> has 1 min", (1 == m1.getMin())); + ensure("3rd insert MMM<U64> has 5 max", (5 == m1.getMax())); + ensure("3rd insert MMM<U64> has 3 mean", (3 == m1.getMean())); + + // Fourth insert + m1.record(U64L(1000000000000)); + ensure("4th insert MMM<U64> has 4 count", (4 == m1.getCount())); + ensure("4th insert MMM<U64> has 1 min", (1 == m1.getMin())); + ensure("4th insert MMM<U64> has 1000000000000ULL max", (U64L(1000000000000) == m1.getMax())); + ensure("4th insert MMM<U64> has 250000000002ULL mean", (U64L( 250000000002) == m1.getMean())); + + // Reset + m1.reset(); + ensure("Reset MMM<U64> has 0 count", (0 == m1.getCount())); + ensure("Reset MMM<U64> has 0 min", (zero == m1.getMin())); + ensure("Reset MMM<U64> has 0 max", (zero == m1.getMax())); + ensure("Reset MMM<U64> has 0 mean no div-by-zero", (zero == m1.getMean())); + } + + // Testing LLSimpleStatMMM's response to large values + template<> template<> + void stat_counter_index_object_t::test<11>() + { + LLSimpleStatMMM<U64> m1; + typedef LLSimpleStatMMM<U64>::Value lcl_int; + lcl_int zero(0); + + // Insert overflowing values + const lcl_int bignum(U64L(0xffffffffffffffff) / 2); + + m1.record(bignum); + m1.record(bignum); + m1.record(bignum); + m1.record(bignum); + m1.record(bignum); + m1.record(bignum); + m1.record(bignum); + m1.record(zero); + + ensure("Overflowed MMM<U64> has 8 count", (8 == m1.getCount())); + ensure("Overflowed MMM<U64> has 0 min", (zero == m1.getMin())); + ensure("Overflowed MMM<U64> has huge max", (bignum == m1.getMax())); + ensure("Overflowed MMM<U64> has fetchable mean", (zero == m1.getMean() || true)); + } + + // Testing LLSimpleStatCounter's merge() method + template<> template<> + void stat_counter_index_object_t::test<12>() + { + LLSimpleStatCounter c1; + LLSimpleStatCounter c2; + + ++c1; + ++c1; + ++c1; + ++c1; + + ++c2; + ++c2; + c2.merge(c1); + + ensure_equals("4 merged into 2 results in 6", 6, c2.getCount()); + + ensure_equals("Source of merge is undamaged", 4, c1.getCount()); + } + + // Testing LLSimpleStatMMM's merge() method + template<> template<> + void stat_counter_index_object_t::test<13>() + { + LLSimpleStatMMM<> m1; + LLSimpleStatMMM<> m2; + + m1.record(3.5); + m1.record(4.5); + m1.record(5.5); + m1.record(6.5); + + m2.record(5.0); + m2.record(7.0); + m2.record(9.0); + + m2.merge(m1); + + ensure_equals("Count after merge (p1)", 7, m2.getCount()); + ensure_approximately_equals("Min after merge (p1)", F32(3.5), m2.getMin(), 22); + ensure_approximately_equals("Max after merge (p1)", F32(9.0), m2.getMax(), 22); + ensure_approximately_equals("Mean after merge (p1)", F32(41.000/7.000), m2.getMean(), 22); + + + ensure_equals("Source count of merge is undamaged (p1)", 4, m1.getCount()); + ensure_approximately_equals("Source min of merge is undamaged (p1)", F32(3.5), m1.getMin(), 22); + ensure_approximately_equals("Source max of merge is undamaged (p1)", F32(6.5), m1.getMax(), 22); + ensure_approximately_equals("Source mean of merge is undamaged (p1)", F32(5.0), m1.getMean(), 22); + + m2.reset(); + + m2.record(-22.0); + m2.record(-1.0); + m2.record(30.0); + + m2.merge(m1); + + ensure_equals("Count after merge (p2)", 7, m2.getCount()); + ensure_approximately_equals("Min after merge (p2)", F32(-22.0), m2.getMin(), 22); + ensure_approximately_equals("Max after merge (p2)", F32(30.0), m2.getMax(), 22); + ensure_approximately_equals("Mean after merge (p2)", F32(27.000/7.000), m2.getMean(), 22); + + } + + // Testing LLSimpleStatMMM's merge() method when src contributes nothing + template<> template<> + void stat_counter_index_object_t::test<14>() + { + LLSimpleStatMMM<> m1; + LLSimpleStatMMM<> m2; + + m2.record(5.0); + m2.record(7.0); + m2.record(9.0); + + m2.merge(m1); + + ensure_equals("Count after merge (p1)", 3, m2.getCount()); + ensure_approximately_equals("Min after merge (p1)", F32(5.0), m2.getMin(), 22); + ensure_approximately_equals("Max after merge (p1)", F32(9.0), m2.getMax(), 22); + ensure_approximately_equals("Mean after merge (p1)", F32(7.000), m2.getMean(), 22); + + ensure_equals("Source count of merge is undamaged (p1)", 0, m1.getCount()); + ensure_approximately_equals("Source min of merge is undamaged (p1)", F32(0), m1.getMin(), 22); + ensure_approximately_equals("Source max of merge is undamaged (p1)", F32(0), m1.getMax(), 22); + ensure_approximately_equals("Source mean of merge is undamaged (p1)", F32(0), m1.getMean(), 22); + + m2.reset(); + + m2.record(-22.0); + m2.record(-1.0); + + m2.merge(m1); + + ensure_equals("Count after merge (p2)", 2, m2.getCount()); + ensure_approximately_equals("Min after merge (p2)", F32(-22.0), m2.getMin(), 22); + ensure_approximately_equals("Max after merge (p2)", F32(-1.0), m2.getMax(), 22); + ensure_approximately_equals("Mean after merge (p2)", F32(-11.5), m2.getMean(), 22); + } + + // Testing LLSimpleStatMMM's merge() method when dst contributes nothing + template<> template<> + void stat_counter_index_object_t::test<15>() + { + LLSimpleStatMMM<> m1; + LLSimpleStatMMM<> m2; + + m1.record(5.0); + m1.record(7.0); + m1.record(9.0); + + m2.merge(m1); + + ensure_equals("Count after merge (p1)", 3, m2.getCount()); + ensure_approximately_equals("Min after merge (p1)", F32(5.0), m2.getMin(), 22); + ensure_approximately_equals("Max after merge (p1)", F32(9.0), m2.getMax(), 22); + ensure_approximately_equals("Mean after merge (p1)", F32(7.000), m2.getMean(), 22); + + ensure_equals("Source count of merge is undamaged (p1)", 3, m1.getCount()); + ensure_approximately_equals("Source min of merge is undamaged (p1)", F32(5.0), m1.getMin(), 22); + ensure_approximately_equals("Source max of merge is undamaged (p1)", F32(9.0), m1.getMax(), 22); + ensure_approximately_equals("Source mean of merge is undamaged (p1)", F32(7.0), m1.getMean(), 22); + + m1.reset(); + m2.reset(); + + m1.record(-22.0); + m1.record(-1.0); + + m2.merge(m1); + + ensure_equals("Count after merge (p2)", 2, m2.getCount()); + ensure_approximately_equals("Min after merge (p2)", F32(-22.0), m2.getMin(), 22); + ensure_approximately_equals("Max after merge (p2)", F32(-1.0), m2.getMax(), 22); + ensure_approximately_equals("Mean after merge (p2)", F32(-11.5), m2.getMean(), 22); + } + + // Testing LLSimpleStatMMM's merge() method when neither dst nor src contributes + template<> template<> + void stat_counter_index_object_t::test<16>() + { + LLSimpleStatMMM<> m1; + LLSimpleStatMMM<> m2; + + m2.merge(m1); + + ensure_equals("Count after merge (p1)", 0, m2.getCount()); + ensure_approximately_equals("Min after merge (p1)", F32(0), m2.getMin(), 22); + ensure_approximately_equals("Max after merge (p1)", F32(0), m2.getMax(), 22); + ensure_approximately_equals("Mean after merge (p1)", F32(0), m2.getMean(), 22); + + ensure_equals("Source count of merge is undamaged (p1)", 0, m1.getCount()); + ensure_approximately_equals("Source min of merge is undamaged (p1)", F32(0), m1.getMin(), 22); + ensure_approximately_equals("Source max of merge is undamaged (p1)", F32(0), m1.getMax(), 22); + ensure_approximately_equals("Source mean of merge is undamaged (p1)", F32(0), m1.getMean(), 22); + } +} diff --git a/indra/newview/tests/llslurl_test.cpp b/indra/newview/tests/llslurl_test.cpp new file mode 100644 index 0000000000..f96f79006a --- /dev/null +++ b/indra/newview/tests/llslurl_test.cpp @@ -0,0 +1,260 @@ +/** + * @file llsecapi_test.cpp + * @author Roxie + * @date 2009-02-10 + * @brief Test the sec api functionality + * + * $LicenseInfo:firstyear=2009&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ +#include "../llviewerprecompiledheaders.h" +#include "../llviewernetwork.h" +#include "../test/lltut.h" +#include "../llslurl.h" +#include "../../llxml/llcontrol.h" +#include "llsdserialize.h" +//---------------------------------------------------------------------------- +// Mock objects for the dependencies of the code we're testing + +LLControlGroup::LLControlGroup(const std::string& name) +: LLInstanceTracker<LLControlGroup, std::string>(name) {} +LLControlGroup::~LLControlGroup() {} +BOOL LLControlGroup::declareString(const std::string& name, + const std::string& initial_val, + const std::string& comment, + BOOL persist) {return TRUE;} +void LLControlGroup::setString(const std::string& name, const std::string& val){} + +std::string gCmdLineLoginURI; +std::string gCmdLineGridChoice; +std::string gCmdLineHelperURI; +std::string gLoginPage; +std::string gCurrentGrid; +std::string LLControlGroup::getString(const std::string& name) +{ + if (name == "CmdLineGridChoice") + return gCmdLineGridChoice; + else if (name == "CmdLineHelperURI") + return gCmdLineHelperURI; + else if (name == "LoginPage") + return gLoginPage; + else if (name == "CurrentGrid") + return gCurrentGrid; + return ""; +} + +LLSD LLControlGroup::getLLSD(const std::string& name) +{ + if (name == "CmdLineLoginURI") + { + if(!gCmdLineLoginURI.empty()) + { + return LLSD(gCmdLineLoginURI); + } + } + return LLSD(); +} + +LLPointer<LLControlVariable> LLControlGroup::getControl(const std::string& name) +{ + ctrl_name_table_t::iterator iter = mNameTable.find(name); + return iter == mNameTable.end() ? LLPointer<LLControlVariable>() : iter->second; +} + +LLControlGroup gSavedSettings("test"); + +// ------------------------------------------------------------------------------------------- +// TUT +// ------------------------------------------------------------------------------------------- +namespace tut +{ + // Test wrapper declaration : wrapping nothing for the moment + struct slurlTest + { + slurlTest() + { + LLGridManager::getInstance()->initialize(std::string("")); + } + ~slurlTest() + { + } + }; + + // Tut templating thingamagic: test group, object and test instance + typedef test_group<slurlTest> slurlTestFactory; + typedef slurlTestFactory::object slurlTestObject; + tut::slurlTestFactory tut_test("LLSlurl"); + + // --------------------------------------------------------------------------------------- + // Test functions + // --------------------------------------------------------------------------------------- + // construction from slurl string + template<> template<> + void slurlTestObject::test<1>() + { + LLGridManager::getInstance()->setGridChoice("util.agni.lindenlab.com"); + + LLSLURL slurl = LLSLURL(""); + ensure_equals("null slurl", (int)slurl.getType(), LLSLURL::LAST_LOCATION); + + slurl = LLSLURL("http://slurl.com/secondlife/myregion"); + ensure_equals("slurl.com slurl, region only - type", slurl.getType(), LLSLURL::LOCATION); + ensure_equals("slurl.com slurl, region only", slurl.getSLURLString(), + "http://maps.secondlife.com/secondlife/myregion/128/128/0"); + + slurl = LLSLURL("http://maps.secondlife.com/secondlife/myregion/1/2/3"); + ensure_equals("maps.secondlife.com slurl, region + coords - type", slurl.getType(), LLSLURL::LOCATION); + ensure_equals("maps.secondlife.com slurl, region + coords", slurl.getSLURLString(), + "http://maps.secondlife.com/secondlife/myregion/1/2/3"); + + slurl = LLSLURL("secondlife://myregion"); + ensure_equals("secondlife: slurl, region only - type", slurl.getType(), LLSLURL::LOCATION); + ensure_equals("secondlife: slurl, region only", slurl.getSLURLString(), + "http://maps.secondlife.com/secondlife/myregion/128/128/0"); + + slurl = LLSLURL("secondlife://myregion/1/2/3"); + ensure_equals("secondlife: slurl, region + coords - type", slurl.getType(), LLSLURL::LOCATION); + ensure_equals("secondlife slurl, region + coords", slurl.getSLURLString(), + "http://maps.secondlife.com/secondlife/myregion/1/2/3"); + + slurl = LLSLURL("/myregion"); + ensure_equals("/region slurl, region- type", slurl.getType(), LLSLURL::LOCATION); + ensure_equals("/region slurl, region ", slurl.getSLURLString(), + "http://maps.secondlife.com/secondlife/myregion/128/128/0"); + + slurl = LLSLURL("/myregion/1/2/3"); + ensure_equals("/: slurl, region + coords - type", slurl.getType(), LLSLURL::LOCATION); + ensure_equals("/ slurl, region + coords", slurl.getSLURLString(), + "http://maps.secondlife.com/secondlife/myregion/1/2/3"); + + slurl = LLSLURL("my region/1/2/3"); + ensure_equals(" slurl, region + coords - type", slurl.getType(), LLSLURL::LOCATION); + ensure_equals(" slurl, region + coords", slurl.getSLURLString(), + "http://maps.secondlife.com/secondlife/my%20region/1/2/3"); + + LLGridManager::getInstance()->setGridChoice("my.grid.com"); + slurl = LLSLURL("https://my.grid.com/region/my%20region/1/2/3"); + ensure_equals("grid slurl, region + coords - type", slurl.getType(), LLSLURL::LOCATION); + ensure_equals("grid slurl, region + coords", slurl.getSLURLString(), + "https://my.grid.com/region/my%20region/1/2/3"); + + slurl = LLSLURL("https://my.grid.com/region/my region"); + ensure_equals("grid slurl, region + coords - type", slurl.getType(), LLSLURL::LOCATION); + ensure_equals("grid slurl, region + coords", slurl.getSLURLString(), + "https://my.grid.com/region/my%20region/128/128/0"); + + LLGridManager::getInstance()->setGridChoice("foo.bar.com"); + slurl = LLSLURL("/myregion/1/2/3"); + ensure_equals("/: slurl, region + coords - type", slurl.getType(), LLSLURL::LOCATION); + ensure_equals("/ slurl, region + coords", slurl.getSLURLString(), + "https://foo.bar.com/region/myregion/1/2/3"); + + slurl = LLSLURL("myregion/1/2/3"); + ensure_equals(": slurl, region + coords - type", slurl.getType(), LLSLURL::LOCATION); + ensure_equals(" slurl, region + coords", slurl.getSLURLString(), + "https://foo.bar.com/region/myregion/1/2/3"); + + slurl = LLSLURL(LLSLURL::SIM_LOCATION_HOME); + ensure_equals("home", slurl.getType(), LLSLURL::HOME_LOCATION); + + slurl = LLSLURL(LLSLURL::SIM_LOCATION_LAST); + ensure_equals("last", slurl.getType(), LLSLURL::LAST_LOCATION); + + slurl = LLSLURL("secondlife:///app/foo/bar?12345"); + ensure_equals("app", slurl.getType(), LLSLURL::APP); + ensure_equals("appcmd", slurl.getAppCmd(), "foo"); + ensure_equals("apppath", slurl.getAppPath().size(), 1); + ensure_equals("apppath2", slurl.getAppPath()[0].asString(), "bar"); + ensure_equals("appquery", slurl.getAppQuery(), "12345"); + ensure_equals("grid1", "foo.bar.com", slurl.getGrid()); + + slurl = LLSLURL("secondlife://Aditi/app/foo/bar?12345"); + ensure_equals("app", slurl.getType(), LLSLURL::APP); + ensure_equals("appcmd", slurl.getAppCmd(), "foo"); + ensure_equals("apppath", slurl.getAppPath().size(), 1); + ensure_equals("apppath2", slurl.getAppPath()[0].asString(), "bar"); + ensure_equals("appquery", slurl.getAppQuery(), "12345"); + ensure_equals("grid2", "util.aditi.lindenlab.com", slurl.getGrid()); + + LLGridManager::getInstance()->setGridChoice("foo.bar.com"); + slurl = LLSLURL("secondlife:///secondlife/myregion/1/2/3"); + ensure_equals("/: slurl, region + coords - type", slurl.getType(), LLSLURL::LOCATION); + ensure_equals("location", slurl.getType(), LLSLURL::LOCATION); + ensure_equals("region" , "myregion", slurl.getRegion()); + ensure_equals("grid3", "util.agni.lindenlab.com", slurl.getGrid()); + + slurl = LLSLURL("secondlife://Aditi/secondlife/myregion/1/2/3"); + ensure_equals("/: slurl, region + coords - type", slurl.getType(), LLSLURL::LOCATION); + ensure_equals("location", slurl.getType(), LLSLURL::LOCATION); + ensure_equals("region" , "myregion", slurl.getRegion()); + ensure_equals("grid4", "util.aditi.lindenlab.com", slurl.getGrid()); + + LLGridManager::getInstance()->setGridChoice("my.grid.com"); + slurl = LLSLURL("https://my.grid.com/app/foo/bar?12345"); + ensure_equals("app", slurl.getType(), LLSLURL::APP); + ensure_equals("appcmd", slurl.getAppCmd(), "foo"); + ensure_equals("apppath", slurl.getAppPath().size(), 1); + ensure_equals("apppath2", slurl.getAppPath()[0].asString(), "bar"); + ensure_equals("appquery", slurl.getAppQuery(), "12345"); + + } + + // construction from grid/region/vector combos + template<> template<> + void slurlTestObject::test<2>() + { + LLSLURL slurl = LLSLURL("mygrid.com", "my region"); + ensure_equals("grid/region - type", slurl.getType(), LLSLURL::LOCATION); + ensure_equals("grid/region", slurl.getSLURLString(), + "https://mygrid.com/region/my%20region/128/128/0"); + + slurl = LLSLURL("mygrid.com", "my region", LLVector3(1,2,3)); + ensure_equals("grid/region/vector - type", slurl.getType(), LLSLURL::LOCATION); + ensure_equals(" grid/region/vector", slurl.getSLURLString(), + "https://mygrid.com/region/my%20region/1/2/3"); + + LLGridManager::getInstance()->setGridChoice("foo.bar.com.bar"); + slurl = LLSLURL("my region", LLVector3(1,2,3)); + ensure_equals("grid/region/vector - type", slurl.getType(), LLSLURL::LOCATION); + ensure_equals(" grid/region/vector", slurl.getSLURLString(), + "https://foo.bar.com.bar/region/my%20region/1/2/3"); + + LLGridManager::getInstance()->setGridChoice("util.agni.lindenlab.com"); + slurl = LLSLURL("my region", LLVector3(1,2,3)); + ensure_equals("default grid/region/vector - type", slurl.getType(), LLSLURL::LOCATION); + ensure_equals(" default grid/region/vector", slurl.getSLURLString(), + "http://maps.secondlife.com/secondlife/my%20region/1/2/3"); + + } + // Accessors + template<> template<> + void slurlTestObject::test<3>() + { + LLGridManager::getInstance()->setGridChoice("my.grid.com"); + LLSLURL slurl = LLSLURL("https://my.grid.com/region/my%20region/1/2/3"); + ensure_equals("login string", slurl.getLoginString(), "uri:my region&1&2&3"); + ensure_equals("location string", slurl.getLocationString(), "my region/1/2/3"); + ensure_equals("grid", slurl.getGrid(), "my.grid.com"); + ensure_equals("region", slurl.getRegion(), "my region"); + ensure_equals("position", slurl.getPosition(), LLVector3(1, 2, 3)); + + } +} diff --git a/indra/newview/tests/lltextureinfo_test.cpp b/indra/newview/tests/lltextureinfo_test.cpp new file mode 100644 index 0000000000..73ace1de37 --- /dev/null +++ b/indra/newview/tests/lltextureinfo_test.cpp @@ -0,0 +1,278 @@ +/** + * @file llwtextureinfo_test.cpp + * @author Si & Gabriel + * @date 2009-03-30 + * + * $LicenseInfo:firstyear=2006&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +// Precompiled header: almost always required for newview cpp files +#include "../llviewerprecompiledheaders.h" +// Class to test +#include "../lltextureinfo.h" +// Dependencies +#include "../lltextureinfodetails.cpp" + +// Tut header +#include "../test/lltut.h" + +// ------------------------------------------------------------------------------------------- +// Stubbing: Declarations required to link and run the class being tested +// Notes: +// * Add here stubbed implementation of the few classes and methods used in the class to be tested +// * Add as little as possible (let the link errors guide you) +// * Do not make any assumption as to how those classes or methods work (i.e. don't copy/paste code) +// * A simulator for a class can be implemented here. Please comment and document thoroughly. + + +// End Stubbing +// ------------------------------------------------------------------------------------------- + +// ------------------------------------------------------------------------------------------- +// TUT +// ------------------------------------------------------------------------------------------- + +namespace tut +{ + // Test wrapper declarations + struct textureinfo_test + { + // Constructor and destructor of the test wrapper + textureinfo_test() + { + } + ~textureinfo_test() + { + } + }; + + // Tut templating thingamagic: test group, object and test instance + typedef test_group<textureinfo_test> textureinfo_t; + typedef textureinfo_t::object textureinfo_object_t; + tut::textureinfo_t tut_textureinfo("LLTectureInfo"); + + + // --------------------------------------------------------------------------------------- + // Test functions + // Notes: + // * Test as many as you possibly can without requiring a full blown simulation of everything + // * The tests are executed in sequence so the test instance state may change between calls + // * Remember that you cannot test private methods with tut + // --------------------------------------------------------------------------------------- + + // --------------------------------------------------------------------------------------- + // Test the LLTextureInfo + // --------------------------------------------------------------------------------------- + + + // Test instantiation + template<> template<> + void textureinfo_object_t::test<1>() + { + LLTextureInfo tex_info; + tex_info.setUpLogging(true, true); + ensure("have we crashed?", true); + } + + // Check lltextureinfo does not contain UUIDs we haven't added + template<> template<> + void textureinfo_object_t::test<2>() + { + LLTextureInfo tex_info; + tex_info.setUpLogging(true, true); + + LLUUID nonExistant("3a0efa3b-84dc-4e17-9b8c-79ea028850c1"); + ensure(!tex_info.has(nonExistant)); + } + + // Check we can add a request time for a texture + template<> template<> + void textureinfo_object_t::test<3>() + { + LLTextureInfo tex_info; + tex_info.setUpLogging(true, true); + + LLUUID id("10e65d70-46fd-429f-841a-bf698e9424d3"); + tex_info.setRequestStartTime(id, 200); + + ensure_equals(tex_info.getRequestStartTime(id), 200); + } + + // Check time for non-existant texture + template<> template<> + void textureinfo_object_t::test<4>() + { + LLTextureInfo tex_info; + tex_info.setUpLogging(true, true); + + LLUUID nonExistant("3a0efa3b-84dc-4e17-9b8c-79ea028850c1"); + ensure_equals(tex_info.getRequestStartTime(nonExistant), 0); + } + + // Check download complete time for non existant texture + template<> template<> + void textureinfo_object_t::test<5>() + { + LLTextureInfo tex_info; + tex_info.setUpLogging(true, true); + + LLUUID nonExistant("3a0efa3b-84dc-4e17-9b8c-79ea028850c1"); + ensure_equals(tex_info.getRequestCompleteTime(nonExistant), 0); + } + + // requested size is passed in correctly + template<> template<> + void textureinfo_object_t::test<6>() + { + LLTextureInfo tex_info; + tex_info.setUpLogging(true, true); + + LLUUID id("10e65d70-46fd-429f-841a-bf698e9424d3"); + tex_info.setRequestSize(id, 600); + + ensure_equals(tex_info.getRequestSize(id), 600); + } + + // transport type is recorded correctly (http) + template<> template<> + void textureinfo_object_t::test<7>() + { + LLTextureInfo tex_info; + tex_info.setUpLogging(true, true); + + LLUUID id("10e65d70-46fd-429f-841a-bf698e9424d3"); + tex_info.setRequestType(id, LLTextureInfoDetails::REQUEST_TYPE_HTTP); + + ensure_equals(tex_info.getRequestType(id), LLTextureInfoDetails::REQUEST_TYPE_HTTP); + } + + // transport type is recorded correctly (udp) + template<> template<> + void textureinfo_object_t::test<8>() + { + LLTextureInfo tex_info; + tex_info.setUpLogging(true, true); + + LLUUID id("10e65d70-46fd-429f-841a-bf698e9424d3"); + tex_info.setRequestType(id, LLTextureInfoDetails::REQUEST_TYPE_UDP); + + ensure_equals(tex_info.getRequestType(id), LLTextureInfoDetails::REQUEST_TYPE_UDP); + } + + // request offset is recorded correctly + template<> template<> + void textureinfo_object_t::test<9>() + { + LLTextureInfo tex_info; + tex_info.setUpLogging(true, true); + + LLUUID id("10e65d70-46fd-429f-841a-bf698e9424d3"); + tex_info.setRequestOffset(id, 1234); + + ensure_equals(tex_info.getRequestOffset(id), 1234); + } + + // ask for averages gives us correct figure + template<> template<> + void textureinfo_object_t::test<10>() + { + LLTextureInfo tex_info; + tex_info.setUpLogging(true, true); + + S32 requestStartTimeOne = 200; + S32 requestEndTimeOne = 400; + S32 requestSizeOne = 1024; + S32 requestSizeOneBits = requestSizeOne * 8; + LLUUID id1("10e65d70-46fd-429f-841a-bf698e9424d3"); + tex_info.setRequestStartTime(id1, requestStartTimeOne); + tex_info.setRequestSize(id1, requestSizeOne); + tex_info.setRequestType(id1, LLTextureInfoDetails::REQUEST_TYPE_HTTP); + tex_info.setRequestCompleteTimeAndLog(id1, requestEndTimeOne); + + U32 requestStartTimeTwo = 100; + U32 requestEndTimeTwo = 500; + U32 requestSizeTwo = 2048; + S32 requestSizeTwoBits = requestSizeTwo * 8; + LLUUID id2("10e65d70-46fd-429f-841a-bf698e9424d4"); + tex_info.setRequestStartTime(id2, requestStartTimeTwo); + tex_info.setRequestSize(id2, requestSizeTwo); + tex_info.setRequestType(id2, LLTextureInfoDetails::REQUEST_TYPE_HTTP); + tex_info.setRequestCompleteTimeAndLog(id2, requestEndTimeTwo); + + S32 averageBitRate = ((requestSizeOneBits/(requestEndTimeOne - requestStartTimeOne)) + + (requestSizeTwoBits/(requestEndTimeTwo - requestStartTimeTwo))) / 2; + + S32 totalBytes = requestSizeOne + requestSizeTwo; + + LLSD results = tex_info.getAverages(); + ensure_equals("is average bits per second correct", results["bits_per_second"].asInteger(), averageBitRate); + ensure_equals("is total bytes is correct", results["bytes_downloaded"].asInteger(), totalBytes); + ensure_equals("is transport correct", results["transport"].asString(), std::string("HTTP")); + } + + // make sure averages cleared when reset is called + template<> template<> + void textureinfo_object_t::test<11>() + { + LLTextureInfo tex_info; + tex_info.setUpLogging(true, true); + + S32 requestStartTimeOne = 200; + S32 requestEndTimeOne = 400; + S32 requestSizeOne = 1024; + LLUUID id1("10e65d70-46fd-429f-841a-bf698e9424d3"); + tex_info.setRequestStartTime(id1, requestStartTimeOne); + tex_info.setRequestSize(id1, requestSizeOne); + tex_info.setRequestType(id1, LLTextureInfoDetails::REQUEST_TYPE_HTTP); + tex_info.setRequestCompleteTimeAndLog(id1, requestEndTimeOne); + + tex_info.getAverages(); + tex_info.reset(); + LLSD results = tex_info.getAverages(); + ensure_equals("is average bits per second correct", results["bits_per_second"].asInteger(), 0); + ensure_equals("is total bytes is correct", results["bytes_downloaded"].asInteger(), 0); + ensure_equals("is transport correct", results["transport"].asString(), std::string("NONE")); + } + + // make sure map item removed when expired + template<> template<> + void textureinfo_object_t::test<12>() + { + LLTextureInfo tex_info; + tex_info.setUpLogging(true, true); + + S32 requestStartTimeOne = 200; + S32 requestEndTimeOne = 400; + S32 requestSizeOne = 1024; + LLUUID id1("10e65d70-46fd-429f-841a-bf698e9424d3"); + tex_info.setRequestStartTime(id1, requestStartTimeOne); + tex_info.setRequestSize(id1, requestSizeOne); + tex_info.setRequestType(id1, LLTextureInfoDetails::REQUEST_TYPE_HTTP); + + ensure_equals("map item created", tex_info.getTextureInfoMapSize(), 1); + + tex_info.setRequestCompleteTimeAndLog(id1, requestEndTimeOne); + + ensure_equals("map item removed when consumed", tex_info.getTextureInfoMapSize(), 0); + } +} + diff --git a/indra/newview/tests/lltextureinfodetails_test.cpp b/indra/newview/tests/lltextureinfodetails_test.cpp new file mode 100644 index 0000000000..31ec5f9d4e --- /dev/null +++ b/indra/newview/tests/lltextureinfodetails_test.cpp @@ -0,0 +1,92 @@ +/** + * @file llwtextureinfodetails_test.cpp + * @author Si & Gabriel + * @date 2009-03-30 + * + * $LicenseInfo:firstyear=2006&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +// Precompiled header: almost always required for newview cpp files +#include "../llviewerprecompiledheaders.h" +// Class to test +#include "../lltextureinfodetails.h" +// Dependencies + +// Tut header +#include "../test/lltut.h" + +// ------------------------------------------------------------------------------------------- +// Stubbing: Declarations required to link and run the class being tested +// Notes: +// * Add here stubbed implementation of the few classes and methods used in the class to be tested +// * Add as little as possible (let the link errors guide you) +// * Do not make any assumption as to how those classes or methods work (i.e. don't copy/paste code) +// * A simulator for a class can be implemented here. Please comment and document thoroughly. + + +// End Stubbing +// ------------------------------------------------------------------------------------------- + +// ------------------------------------------------------------------------------------------- +// TUT +// ------------------------------------------------------------------------------------------- + +namespace tut +{ + // Test wrapper declarations + struct textureinfodetails_test + { + // Constructor and destructor of the test wrapper + textureinfodetails_test() + { + } + ~textureinfodetails_test() + { + } + }; + + // Tut templating thingamagic: test group, object and test instance + typedef test_group<textureinfodetails_test> textureinfodetails_t; + typedef textureinfodetails_t::object textureinfodetails_object_t; + tut::textureinfodetails_t tut_textureinfodetails("LLTextureInfoDetails"); + + + // --------------------------------------------------------------------------------------- + // Test functions + // Notes: + // * Test as many as you possibly can without requiring a full blown simulation of everything + // * The tests are executed in sequence so the test instance state may change between calls + // * Remember that you cannot test private methods with tut + // --------------------------------------------------------------------------------------- + + // --------------------------------------------------------------------------------------- + // Test the LLTextureInfo + // --------------------------------------------------------------------------------------- + + + // Test instantiation + template<> template<> + void textureinfodetails_object_t::test<1>() + { + ensure("have we crashed?", true); + } +} diff --git a/indra/newview/tests/lltexturestatsuploader_test.cpp b/indra/newview/tests/lltexturestatsuploader_test.cpp new file mode 100644 index 0000000000..cfb2c267cc --- /dev/null +++ b/indra/newview/tests/lltexturestatsuploader_test.cpp @@ -0,0 +1,150 @@ +/** + * @file lltexturestatsuploader_test.cpp + * @author Si + * @date 2009-05-27 + * + * $LicenseInfo:firstyear=2006&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +// Precompiled header: almost always required for newview cpp files +#include "../llviewerprecompiledheaders.h" +// Class to test +#include "../lltexturestatsuploader.h" +// Dependencies + +// Tut header +#include "../test/lltut.h" + +// ------------------------------------------------------------------------------------------- +// Stubbing: Declarations required to link and run the class being tested +// Notes: +// * Add here stubbed implementation of the few classes and methods used in the class to be tested +// * Add as little as possible (let the link errors guide you) +// * Do not make any assumption as to how those classes or methods work (i.e. don't copy/paste code) +// * A simulator for a class can be implemented here. Please comment and document thoroughly. + +#include "boost/intrusive_ptr.hpp" +void boost::intrusive_ptr_add_ref(LLCurl::Responder*){} +void boost::intrusive_ptr_release(LLCurl::Responder* p){} +const F32 HTTP_REQUEST_EXPIRY_SECS = 0.0f; + +static std::string most_recent_url; +static LLSD most_recent_body; + +void LLHTTPClient::post( + const std::string& url, + const LLSD& body, + ResponderPtr, + const LLSD& headers, + const F32 timeout) +{ + // set some sensor code + most_recent_url = url; + most_recent_body = body; + return; +} + +// End Stubbing +// ------------------------------------------------------------------------------------------- + +// ------------------------------------------------------------------------------------------- +// TUT +// ------------------------------------------------------------------------------------------- + +namespace tut +{ + // Test wrapper declarations + struct texturestatsuploader_test + { + // Constructor and destructor of the test wrapper + texturestatsuploader_test() + { + most_recent_url = "some sort of default text that should never match anything the tests are expecting!"; + LLSD blank_llsd; + most_recent_body = blank_llsd; + } + ~texturestatsuploader_test() + { + } + }; + + // Tut templating thingamagic: test group, object and test instance + typedef test_group<texturestatsuploader_test> texturestatsuploader_t; + typedef texturestatsuploader_t::object texturestatsuploader_object_t; + tut::texturestatsuploader_t tut_texturestatsuploader("LLTextureStatsUploader"); + + + // --------------------------------------------------------------------------------------- + // Test functions + // Notes: + // * Test as many as you possibly can without requiring a full blown simulation of everything + // * The tests are executed in sequence so the test instance state may change between calls + // * Remember that you cannot test private methods with tut + // --------------------------------------------------------------------------------------- + + // --------------------------------------------------------------------------------------- + // Test the LLTextureInfo + // --------------------------------------------------------------------------------------- + + + // Test instantiation + template<> template<> + void texturestatsuploader_object_t::test<1>() + { + LLTextureStatsUploader tsu; + llinfos << &tsu << llendl; + ensure("have we crashed?", true); + } + + // does it call out to the provided url if we ask it to? + template<> template<> + void texturestatsuploader_object_t::test<2>() + { + LLTextureStatsUploader tsu; + std::string url = "http://blahblahblah"; + LLSD texture_stats; + tsu.uploadStatsToSimulator(url, texture_stats); + ensure_equals("did the right url get called?", most_recent_url, url); + ensure_equals("did the right body get sent?", most_recent_body, texture_stats); + } + + // does it not call out to the provided url if we send it an ungranted cap? + template<> template<> + void texturestatsuploader_object_t::test<3>() + { + LLTextureStatsUploader tsu; + + // this url left intentionally blank to mirror + // not getting a cap in the caller. + std::string url_for_ungranted_cap = ""; + + LLSD texture_stats; + std::string most_recent_url_before_test = most_recent_url; + tsu.uploadStatsToSimulator(url_for_ungranted_cap, texture_stats); + + ensure_equals("hopefully no url got called!", most_recent_url, most_recent_url_before_test); + } + + // does it call out if the data is empty? + // should it even do that? +} + diff --git a/indra/newview/tests/llversioninfo_test.cpp b/indra/newview/tests/llversioninfo_test.cpp new file mode 100644 index 0000000000..398d8f16ed --- /dev/null +++ b/indra/newview/tests/llversioninfo_test.cpp @@ -0,0 +1,114 @@ +/** + * @file llversioninfo_test.cpp + * + * $LicenseInfo:firstyear=2010&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "linden_common.h" + +#include "../test/lltut.h" + +#include "../llversioninfo.h" +#include "llversionviewer.h" + +namespace tut +{ + struct versioninfo + { + versioninfo() + : mResetChannel("Reset Channel") + { + std::ostringstream stream; + stream << LL_VERSION_MAJOR << "." + << LL_VERSION_MINOR << "." + << LL_VERSION_PATCH << "." + << LL_VERSION_BUILD; + mVersion = stream.str(); + stream.str(""); + + stream << LL_VERSION_MAJOR << "." + << LL_VERSION_MINOR << "." + << LL_VERSION_PATCH; + mShortVersion = stream.str(); + stream.str(""); + + stream << LL_CHANNEL + << " " + << mVersion; + mVersionAndChannel = stream.str(); + stream.str(""); + + stream << mResetChannel + << " " + << mVersion; + mResetVersionAndChannel = stream.str(); + } + std::string mResetChannel; + std::string mVersion; + std::string mShortVersion; + std::string mVersionAndChannel; + std::string mResetVersionAndChannel; + }; + + typedef test_group<versioninfo> versioninfo_t; + typedef versioninfo_t::object versioninfo_object_t; + tut::versioninfo_t tut_versioninfo("LLVersionInfo"); + + template<> template<> + void versioninfo_object_t::test<1>() + { + ensure_equals("Major version", + LLVersionInfo::getMajor(), + LL_VERSION_MAJOR); + ensure_equals("Minor version", + LLVersionInfo::getMinor(), + LL_VERSION_MINOR); + ensure_equals("Patch version", + LLVersionInfo::getPatch(), + LL_VERSION_PATCH); + ensure_equals("Build version", + LLVersionInfo::getBuild(), + LL_VERSION_BUILD); + ensure_equals("Channel version", + LLVersionInfo::getChannel(), + LL_CHANNEL); + + ensure_equals("Version String", + LLVersionInfo::getVersion(), + mVersion); + ensure_equals("Short Version String", + LLVersionInfo::getShortVersion(), + mShortVersion); + ensure_equals("Version and channel String", + LLVersionInfo::getChannelAndVersion(), + mVersionAndChannel); + + LLVersionInfo::resetChannel(mResetChannel); + ensure_equals("Reset channel version", + LLVersionInfo::getChannel(), + mResetChannel); + + ensure_equals("Reset Version and channel String", + LLVersionInfo::getChannelAndVersion(), + mResetVersionAndChannel); + } +} diff --git a/indra/newview/tests/llviewerassetstats_test.cpp b/indra/newview/tests/llviewerassetstats_test.cpp new file mode 100644 index 0000000000..3faddc13c1 --- /dev/null +++ b/indra/newview/tests/llviewerassetstats_test.cpp @@ -0,0 +1,984 @@ +/** + * @file llviewerassetstats_tut.cpp + * @date 2010-10-28 + * @brief Test cases for some of newview/llviewerassetstats.cpp + * + * $LicenseInfo:firstyear=2010&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "linden_common.h" + +#include <tut/tut.hpp> +#include <iostream> + +#include "lltut.h" +#include "../llviewerassetstats.h" +#include "lluuid.h" +#include "llsdutil.h" +#include "llregionhandle.h" + +static const char * all_keys[] = +{ + "duration", + "fps", + "get_other", + "get_texture_temp_http", + "get_texture_temp_udp", + "get_texture_non_temp_http", + "get_texture_non_temp_udp", + "get_wearable_udp", + "get_sound_udp", + "get_gesture_udp" +}; + +static const char * resp_keys[] = +{ + "get_other", + "get_texture_temp_http", + "get_texture_temp_udp", + "get_texture_non_temp_http", + "get_texture_non_temp_udp", + "get_wearable_udp", + "get_sound_udp", + "get_gesture_udp" +}; + +static const char * sub_keys[] = +{ + "dequeued", + "enqueued", + "resp_count", + "resp_max", + "resp_min", + "resp_mean" +}; + +static const char * mmm_resp_keys[] = +{ + "fps" +}; + +static const char * mmm_sub_keys[] = +{ + "count", + "max", + "min", + "mean" +}; + +static const LLUUID region1("4e2d81a3-6263-6ffe-ad5c-8ce04bee07e8"); +static const LLUUID region2("68762cc8-b68b-4e45-854b-e830734f2d4a"); +static const U64 region1_handle(0x0000040000003f00ULL); +static const U64 region2_handle(0x0000030000004200ULL); +static const std::string region1_handle_str("0000040000003f00"); +static const std::string region2_handle_str("0000030000004200"); + +#if 0 +static bool +is_empty_map(const LLSD & sd) +{ + return sd.isMap() && 0 == sd.size(); +} + +static bool +is_single_key_map(const LLSD & sd, const std::string & key) +{ + return sd.isMap() && 1 == sd.size() && sd.has(key); +} +#endif + +static bool +is_double_key_map(const LLSD & sd, const std::string & key1, const std::string & key2) +{ + return sd.isMap() && 2 == sd.size() && sd.has(key1) && sd.has(key2); +} + +static bool +is_no_stats_map(const LLSD & sd) +{ + return is_double_key_map(sd, "duration", "regions"); +} + +static bool +is_single_slot_array(const LLSD & sd, U64 region_handle) +{ + U32 grid_x(0), grid_y(0); + grid_from_region_handle(region_handle, &grid_x, &grid_y); + + return (sd.isArray() && + 1 == sd.size() && + sd[0].has("grid_x") && + sd[0].has("grid_y") && + sd[0]["grid_x"].isInteger() && + sd[0]["grid_y"].isInteger() && + grid_x == sd[0]["grid_x"].asInteger() && + grid_y == sd[0]["grid_y"].asInteger()); +} + +static bool +is_double_slot_array(const LLSD & sd, U64 region_handle1, U64 region_handle2) +{ + U32 grid_x1(0), grid_y1(0); + U32 grid_x2(0), grid_y2(0); + grid_from_region_handle(region_handle1, &grid_x1, &grid_y1); + grid_from_region_handle(region_handle2, &grid_x2, &grid_y2); + + return (sd.isArray() && + 2 == sd.size() && + sd[0].has("grid_x") && + sd[0].has("grid_y") && + sd[0]["grid_x"].isInteger() && + sd[0]["grid_y"].isInteger() && + sd[1].has("grid_x") && + sd[1].has("grid_y") && + sd[1]["grid_x"].isInteger() && + sd[1]["grid_y"].isInteger() && + ((grid_x1 == sd[0]["grid_x"].asInteger() && + grid_y1 == sd[0]["grid_y"].asInteger() && + grid_x2 == sd[1]["grid_x"].asInteger() && + grid_y2 == sd[1]["grid_y"].asInteger()) || + (grid_x1 == sd[1]["grid_x"].asInteger() && + grid_y1 == sd[1]["grid_y"].asInteger() && + grid_x2 == sd[0]["grid_x"].asInteger() && + grid_y2 == sd[0]["grid_y"].asInteger()))); +} + +static LLSD +get_region(const LLSD & sd, U64 region_handle1) +{ + U32 grid_x(0), grid_y(0); + grid_from_region_handle(region_handle1, &grid_x, &grid_y); + + for (LLSD::array_const_iterator it(sd["regions"].beginArray()); + sd["regions"].endArray() != it; + ++it) + { + if ((*it).has("grid_x") && + (*it).has("grid_y") && + (*it)["grid_x"].isInteger() && + (*it)["grid_y"].isInteger() && + (*it)["grid_x"].asInteger() == grid_x && + (*it)["grid_y"].asInteger() == grid_y) + { + return *it; + } + } + return LLSD(); +} + +namespace tut +{ + struct tst_viewerassetstats_index + {}; + typedef test_group<tst_viewerassetstats_index> tst_viewerassetstats_index_t; + typedef tst_viewerassetstats_index_t::object tst_viewerassetstats_index_object_t; + tut::tst_viewerassetstats_index_t tut_tst_viewerassetstats_index("tst_viewerassetstats_test"); + + // Testing free functions without global stats allocated + template<> template<> + void tst_viewerassetstats_index_object_t::test<1>() + { + // Check that helpers aren't bothered by missing global stats + ensure("Global gViewerAssetStatsMain should be NULL", (NULL == gViewerAssetStatsMain)); + + LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_TEXTURE, false, false); + + LLViewerAssetStatsFF::record_dequeue_main(LLViewerAssetType::AT_TEXTURE, false, false); + + LLViewerAssetStatsFF::record_response_main(LLViewerAssetType::AT_GESTURE, false, false, 12300000ULL); + } + + // Create a non-global instance and check the structure + template<> template<> + void tst_viewerassetstats_index_object_t::test<2>() + { + ensure("Global gViewerAssetStatsMain should be NULL", (NULL == gViewerAssetStatsMain)); + + LLViewerAssetStats * it = new LLViewerAssetStats(); + + ensure("Global gViewerAssetStatsMain should still be NULL", (NULL == gViewerAssetStatsMain)); + + LLSD sd_full = it->asLLSD(false); + + // Default (NULL) region ID doesn't produce LLSD results so should + // get an empty map back from output + ensure("Stat-less LLSD initially", is_no_stats_map(sd_full)); + + // Once the region is set, we will get a response even with no data collection + it->setRegion(region1_handle); + sd_full = it->asLLSD(false); + ensure("Correct single-key LLSD map root", is_double_key_map(sd_full, "duration", "regions")); + ensure("Correct single-slot LLSD array regions", is_single_slot_array(sd_full["regions"], region1_handle)); + + LLSD sd = sd_full["regions"][0]; + + delete it; + + // Check the structure of the LLSD + for (int i = 0; i < LL_ARRAY_SIZE(all_keys); ++i) + { + std::string line = llformat("Has '%s' key", all_keys[i]); + ensure(line, sd.has(all_keys[i])); + } + + for (int i = 0; i < LL_ARRAY_SIZE(resp_keys); ++i) + { + for (int j = 0; j < LL_ARRAY_SIZE(sub_keys); ++j) + { + std::string line = llformat("Key '%s' has '%s' key", resp_keys[i], sub_keys[j]); + ensure(line, sd[resp_keys[i]].has(sub_keys[j])); + } + } + + for (int i = 0; i < LL_ARRAY_SIZE(mmm_resp_keys); ++i) + { + for (int j = 0; j < LL_ARRAY_SIZE(mmm_sub_keys); ++j) + { + std::string line = llformat("Key '%s' has '%s' key", mmm_resp_keys[i], mmm_sub_keys[j]); + ensure(line, sd[mmm_resp_keys[i]].has(mmm_sub_keys[j])); + } + } + } + + // Create a non-global instance and check some content + template<> template<> + void tst_viewerassetstats_index_object_t::test<3>() + { + LLViewerAssetStats * it = new LLViewerAssetStats(); + it->setRegion(region1_handle); + + LLSD sd = it->asLLSD(false); + ensure("Correct single-key LLSD map root", is_double_key_map(sd, "regions", "duration")); + ensure("Correct single-slot LLSD array regions", is_single_slot_array(sd["regions"], region1_handle)); + sd = sd[0]; + + delete it; + + // Check a few points on the tree for content + ensure("sd[get_texture_temp_http][dequeued] is 0", (0 == sd["get_texture_temp_http"]["dequeued"].asInteger())); + ensure("sd[get_sound_udp][resp_min] is 0", (0.0 == sd["get_sound_udp"]["resp_min"].asReal())); + } + + // Create a global instance and verify free functions do something useful + template<> template<> + void tst_viewerassetstats_index_object_t::test<4>() + { + gViewerAssetStatsMain = new LLViewerAssetStats(); + LLViewerAssetStatsFF::set_region_main(region1_handle); + + LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_TEXTURE, false, false); + LLViewerAssetStatsFF::record_dequeue_main(LLViewerAssetType::AT_TEXTURE, false, false); + + LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_BODYPART, false, false); + LLViewerAssetStatsFF::record_dequeue_main(LLViewerAssetType::AT_BODYPART, false, false); + + LLSD sd = gViewerAssetStatsMain->asLLSD(false); + ensure("Correct single-key LLSD map root", is_double_key_map(sd, "regions", "duration")); + ensure("Correct single-slot LLSD array regions", is_single_slot_array(sd["regions"], region1_handle)); + sd = sd["regions"][0]; + + // Check a few points on the tree for content + ensure("sd[get_texture_non_temp_udp][enqueued] is 1", (1 == sd["get_texture_non_temp_udp"]["enqueued"].asInteger())); + ensure("sd[get_texture_temp_udp][enqueued] is 0", (0 == sd["get_texture_temp_udp"]["enqueued"].asInteger())); + ensure("sd[get_texture_non_temp_http][enqueued] is 0", (0 == sd["get_texture_non_temp_http"]["enqueued"].asInteger())); + ensure("sd[get_texture_temp_http][enqueued] is 0", (0 == sd["get_texture_temp_http"]["enqueued"].asInteger())); + ensure("sd[get_gesture_udp][dequeued] is 0", (0 == sd["get_gesture_udp"]["dequeued"].asInteger())); + + // Reset and check zeros... + // Reset leaves current region in place + gViewerAssetStatsMain->reset(); + sd = gViewerAssetStatsMain->asLLSD(false)["regions"][region1_handle_str]; + + delete gViewerAssetStatsMain; + gViewerAssetStatsMain = NULL; + + ensure("sd[get_texture_non_temp_udp][enqueued] is reset", (0 == sd["get_texture_non_temp_udp"]["enqueued"].asInteger())); + ensure("sd[get_gesture_udp][dequeued] is reset", (0 == sd["get_gesture_udp"]["dequeued"].asInteger())); + } + + // Create two global instances and verify no interactions + template<> template<> + void tst_viewerassetstats_index_object_t::test<5>() + { + gViewerAssetStatsThread1 = new LLViewerAssetStats(); + gViewerAssetStatsMain = new LLViewerAssetStats(); + LLViewerAssetStatsFF::set_region_main(region1_handle); + + LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_TEXTURE, false, false); + LLViewerAssetStatsFF::record_dequeue_main(LLViewerAssetType::AT_TEXTURE, false, false); + + LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_BODYPART, false, false); + LLViewerAssetStatsFF::record_dequeue_main(LLViewerAssetType::AT_BODYPART, false, false); + + LLSD sd = gViewerAssetStatsThread1->asLLSD(false); + ensure("Other collector is empty", is_no_stats_map(sd)); + sd = gViewerAssetStatsMain->asLLSD(false); + ensure("Correct single-key LLSD map root", is_double_key_map(sd, "regions", "duration")); + ensure("Correct single-slot LLSD array regions", is_single_slot_array(sd["regions"], region1_handle)); + sd = sd["regions"][0]; + + // Check a few points on the tree for content + ensure("sd[get_texture_non_temp_udp][enqueued] is 1", (1 == sd["get_texture_non_temp_udp"]["enqueued"].asInteger())); + ensure("sd[get_texture_temp_udp][enqueued] is 0", (0 == sd["get_texture_temp_udp"]["enqueued"].asInteger())); + ensure("sd[get_texture_non_temp_http][enqueued] is 0", (0 == sd["get_texture_non_temp_http"]["enqueued"].asInteger())); + ensure("sd[get_texture_temp_http][enqueued] is 0", (0 == sd["get_texture_temp_http"]["enqueued"].asInteger())); + ensure("sd[get_gesture_udp][dequeued] is 0", (0 == sd["get_gesture_udp"]["dequeued"].asInteger())); + + // Reset and check zeros... + // Reset leaves current region in place + gViewerAssetStatsMain->reset(); + sd = gViewerAssetStatsMain->asLLSD(false)["regions"][0]; + + delete gViewerAssetStatsMain; + gViewerAssetStatsMain = NULL; + delete gViewerAssetStatsThread1; + gViewerAssetStatsThread1 = NULL; + + ensure("sd[get_texture_non_temp_udp][enqueued] is reset", (0 == sd["get_texture_non_temp_udp"]["enqueued"].asInteger())); + ensure("sd[get_gesture_udp][dequeued] is reset", (0 == sd["get_gesture_udp"]["dequeued"].asInteger())); + } + + // Check multiple region collection + template<> template<> + void tst_viewerassetstats_index_object_t::test<6>() + { + gViewerAssetStatsMain = new LLViewerAssetStats(); + + LLViewerAssetStatsFF::set_region_main(region1_handle); + + LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_TEXTURE, false, false); + LLViewerAssetStatsFF::record_dequeue_main(LLViewerAssetType::AT_TEXTURE, false, false); + + LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_BODYPART, false, false); + LLViewerAssetStatsFF::record_dequeue_main(LLViewerAssetType::AT_BODYPART, false, false); + + LLViewerAssetStatsFF::set_region_main(region2_handle); + + LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_GESTURE, false, false); + LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_GESTURE, false, false); + LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_GESTURE, false, false); + LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_GESTURE, false, false); + + LLSD sd = gViewerAssetStatsMain->asLLSD(false); + + // std::cout << sd << std::endl; + + ensure("Correct double-key LLSD map root", is_double_key_map(sd, "duration", "regions")); + ensure("Correct double-slot LLSD array regions", is_double_slot_array(sd["regions"], region1_handle, region2_handle)); + LLSD sd1 = get_region(sd, region1_handle); + LLSD sd2 = get_region(sd, region2_handle); + ensure("Region1 is present in results", sd1.isMap()); + ensure("Region2 is present in results", sd2.isMap()); + + // Check a few points on the tree for content + ensure_equals("sd1[get_texture_non_temp_udp][enqueued] is 1", sd1["get_texture_non_temp_udp"]["enqueued"].asInteger(), 1); + ensure_equals("sd1[get_texture_temp_udp][enqueued] is 0", sd1["get_texture_temp_udp"]["enqueued"].asInteger(), 0); + ensure_equals("sd1[get_texture_non_temp_http][enqueued] is 0", sd1["get_texture_non_temp_http"]["enqueued"].asInteger(), 0); + ensure_equals("sd1[get_texture_temp_http][enqueued] is 0", sd1["get_texture_temp_http"]["enqueued"].asInteger(), 0); + ensure_equals("sd1[get_gesture_udp][dequeued] is 0", sd1["get_gesture_udp"]["dequeued"].asInteger(), 0); + + // Check a few points on the tree for content + ensure("sd2[get_gesture_udp][enqueued] is 4", (4 == sd2["get_gesture_udp"]["enqueued"].asInteger())); + ensure("sd2[get_gesture_udp][dequeued] is 0", (0 == sd2["get_gesture_udp"]["dequeued"].asInteger())); + ensure("sd2[get_texture_non_temp_udp][enqueued] is 0", (0 == sd2["get_texture_non_temp_udp"]["enqueued"].asInteger())); + + // Reset and check zeros... + // Reset leaves current region in place + gViewerAssetStatsMain->reset(); + sd = gViewerAssetStatsMain->asLLSD(false); + ensure("Correct single-key LLSD map root", is_double_key_map(sd, "regions", "duration")); + ensure("Correct single-slot LLSD array regions (p2)", is_single_slot_array(sd["regions"], region2_handle)); + sd2 = sd["regions"][0]; + + delete gViewerAssetStatsMain; + gViewerAssetStatsMain = NULL; + + ensure("sd2[get_texture_non_temp_udp][enqueued] is reset", (0 == sd2["get_texture_non_temp_udp"]["enqueued"].asInteger())); + ensure("sd2[get_gesture_udp][enqueued] is reset", (0 == sd2["get_gesture_udp"]["enqueued"].asInteger())); + } + + // Check multiple region collection jumping back-and-forth between regions + template<> template<> + void tst_viewerassetstats_index_object_t::test<7>() + { + gViewerAssetStatsMain = new LLViewerAssetStats(); + + LLViewerAssetStatsFF::set_region_main(region1_handle); + + LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_TEXTURE, false, false); + LLViewerAssetStatsFF::record_dequeue_main(LLViewerAssetType::AT_TEXTURE, false, false); + + LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_BODYPART, false, false); + LLViewerAssetStatsFF::record_dequeue_main(LLViewerAssetType::AT_BODYPART, false, false); + + LLViewerAssetStatsFF::set_region_main(region2_handle); + + LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_GESTURE, false, false); + LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_GESTURE, false, false); + LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_GESTURE, false, false); + LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_GESTURE, false, false); + + LLViewerAssetStatsFF::set_region_main(region1_handle); + + LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_TEXTURE, true, true); + LLViewerAssetStatsFF::record_dequeue_main(LLViewerAssetType::AT_TEXTURE, true, true); + + LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_BODYPART, false, false); + LLViewerAssetStatsFF::record_dequeue_main(LLViewerAssetType::AT_BODYPART, false, false); + + LLViewerAssetStatsFF::set_region_main(region2_handle); + + LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_GESTURE, false, false); + LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_GESTURE, false, false); + LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_GESTURE, false, false); + LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_GESTURE, false, false); + + LLSD sd = gViewerAssetStatsMain->asLLSD(false); + + ensure("Correct double-key LLSD map root", is_double_key_map(sd, "duration", "regions")); + ensure("Correct double-slot LLSD array regions", is_double_slot_array(sd["regions"], region1_handle, region2_handle)); + LLSD sd1 = get_region(sd, region1_handle); + LLSD sd2 = get_region(sd, region2_handle); + ensure("Region1 is present in results", sd1.isMap()); + ensure("Region2 is present in results", sd2.isMap()); + + // Check a few points on the tree for content + ensure("sd1[get_texture_non_temp_udp][enqueued] is 1", (1 == sd1["get_texture_non_temp_udp"]["enqueued"].asInteger())); + ensure("sd1[get_texture_temp_udp][enqueued] is 0", (0 == sd1["get_texture_temp_udp"]["enqueued"].asInteger())); + ensure("sd1[get_texture_non_temp_http][enqueued] is 0", (0 == sd1["get_texture_non_temp_http"]["enqueued"].asInteger())); + ensure("sd1[get_texture_temp_http][enqueued] is 1", (1 == sd1["get_texture_temp_http"]["enqueued"].asInteger())); + ensure("sd1[get_gesture_udp][dequeued] is 0", (0 == sd1["get_gesture_udp"]["dequeued"].asInteger())); + + // Check a few points on the tree for content + ensure("sd2[get_gesture_udp][enqueued] is 8", (8 == sd2["get_gesture_udp"]["enqueued"].asInteger())); + ensure("sd2[get_gesture_udp][dequeued] is 0", (0 == sd2["get_gesture_udp"]["dequeued"].asInteger())); + ensure("sd2[get_texture_non_temp_udp][enqueued] is 0", (0 == sd2["get_texture_non_temp_udp"]["enqueued"].asInteger())); + + // Reset and check zeros... + // Reset leaves current region in place + gViewerAssetStatsMain->reset(); + sd = gViewerAssetStatsMain->asLLSD(false); + ensure("Correct single-key LLSD map root", is_double_key_map(sd, "duration", "regions")); + ensure("Correct single-slot LLSD array regions (p2)", is_single_slot_array(sd["regions"], region2_handle)); + sd2 = get_region(sd, region2_handle); + ensure("Region2 is present in results", sd2.isMap()); + + delete gViewerAssetStatsMain; + gViewerAssetStatsMain = NULL; + + ensure_equals("sd2[get_texture_non_temp_udp][enqueued] is reset", sd2["get_texture_non_temp_udp"]["enqueued"].asInteger(), 0); + ensure_equals("sd2[get_gesture_udp][enqueued] is reset", sd2["get_gesture_udp"]["enqueued"].asInteger(), 0); + } + + // Non-texture assets ignore transport and persistence flags + template<> template<> + void tst_viewerassetstats_index_object_t::test<8>() + { + gViewerAssetStatsThread1 = new LLViewerAssetStats(); + gViewerAssetStatsMain = new LLViewerAssetStats(); + LLViewerAssetStatsFF::set_region_main(region1_handle); + + LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_TEXTURE, false, false); + LLViewerAssetStatsFF::record_dequeue_main(LLViewerAssetType::AT_TEXTURE, false, false); + + LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_BODYPART, false, false); + LLViewerAssetStatsFF::record_dequeue_main(LLViewerAssetType::AT_BODYPART, false, false); + + LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_BODYPART, false, true); + LLViewerAssetStatsFF::record_dequeue_main(LLViewerAssetType::AT_BODYPART, false, true); + + LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_BODYPART, true, false); + LLViewerAssetStatsFF::record_dequeue_main(LLViewerAssetType::AT_BODYPART, true, false); + + LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_BODYPART, true, true); + LLViewerAssetStatsFF::record_dequeue_main(LLViewerAssetType::AT_BODYPART, true, true); + + LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_LSL_BYTECODE, false, false); + + LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_LSL_BYTECODE, false, true); + + LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_LSL_BYTECODE, true, false); + + LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + + LLSD sd = gViewerAssetStatsThread1->asLLSD(false); + ensure("Other collector is empty", is_no_stats_map(sd)); + sd = gViewerAssetStatsMain->asLLSD(false); + ensure("Correct single-key LLSD map root", is_double_key_map(sd, "regions", "duration")); + ensure("Correct single-slot LLSD array regions", is_single_slot_array(sd["regions"], region1_handle)); + sd = get_region(sd, region1_handle); + ensure("Region1 is present in results", sd.isMap()); + + // Check a few points on the tree for content + ensure("sd[get_gesture_udp][enqueued] is 0", (0 == sd["get_gesture_udp"]["enqueued"].asInteger())); + ensure("sd[get_gesture_udp][dequeued] is 0", (0 == sd["get_gesture_udp"]["dequeued"].asInteger())); + + ensure("sd[get_wearable_udp][enqueued] is 4", (4 == sd["get_wearable_udp"]["enqueued"].asInteger())); + ensure("sd[get_wearable_udp][dequeued] is 4", (4 == sd["get_wearable_udp"]["dequeued"].asInteger())); + + ensure("sd[get_other][enqueued] is 4", (4 == sd["get_other"]["enqueued"].asInteger())); + ensure("sd[get_other][dequeued] is 0", (0 == sd["get_other"]["dequeued"].asInteger())); + + // Reset and check zeros... + // Reset leaves current region in place + gViewerAssetStatsMain->reset(); + sd = get_region(gViewerAssetStatsMain->asLLSD(false), region1_handle); + ensure("Region1 is present in results", sd.isMap()); + + delete gViewerAssetStatsMain; + gViewerAssetStatsMain = NULL; + delete gViewerAssetStatsThread1; + gViewerAssetStatsThread1 = NULL; + + ensure_equals("sd[get_texture_non_temp_udp][enqueued] is reset", sd["get_texture_non_temp_udp"]["enqueued"].asInteger(), 0); + ensure_equals("sd[get_gesture_udp][dequeued] is reset", sd["get_gesture_udp"]["dequeued"].asInteger(), 0); + } + + + // LLViewerAssetStats::merge() basic functions work + template<> template<> + void tst_viewerassetstats_index_object_t::test<9>() + { + LLViewerAssetStats s1; + LLViewerAssetStats s2; + + s1.setRegion(region1_handle); + s2.setRegion(region1_handle); + + s1.recordGetServiced(LLViewerAssetType::AT_TEXTURE, true, true, 5000000); + s1.recordGetServiced(LLViewerAssetType::AT_TEXTURE, true, true, 6000000); + s1.recordGetServiced(LLViewerAssetType::AT_TEXTURE, true, true, 8000000); + s1.recordGetServiced(LLViewerAssetType::AT_TEXTURE, true, true, 7000000); + s1.recordGetServiced(LLViewerAssetType::AT_TEXTURE, true, true, 9000000); + + s2.recordGetServiced(LLViewerAssetType::AT_TEXTURE, true, true, 2000000); + s2.recordGetServiced(LLViewerAssetType::AT_TEXTURE, true, true, 3000000); + s2.recordGetServiced(LLViewerAssetType::AT_TEXTURE, true, true, 4000000); + + s2.merge(s1); + + LLSD s2_llsd = get_region(s2.asLLSD(false), region1_handle); + ensure("Region1 is present in results", s2_llsd.isMap()); + + ensure_equals("count after merge", s2_llsd["get_texture_temp_http"]["resp_count"].asInteger(), 8); + ensure_approximately_equals("min after merge", s2_llsd["get_texture_temp_http"]["resp_min"].asReal(), 2.0, 22); + ensure_approximately_equals("max after merge", s2_llsd["get_texture_temp_http"]["resp_max"].asReal(), 9.0, 22); + ensure_approximately_equals("max after merge", s2_llsd["get_texture_temp_http"]["resp_mean"].asReal(), 5.5, 22); + } + + // LLViewerAssetStats::merge() basic functions work without corrupting source data + template<> template<> + void tst_viewerassetstats_index_object_t::test<10>() + { + LLViewerAssetStats s1; + LLViewerAssetStats s2; + + s1.setRegion(region1_handle); + s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + + s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + + s1.recordGetServiced(LLViewerAssetType::AT_LSL_BYTECODE, true, true, 23289200); + s1.recordGetServiced(LLViewerAssetType::AT_LSL_BYTECODE, true, true, 282900); + + + s2.setRegion(region2_handle); + s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + + s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + + s2.recordGetServiced(LLViewerAssetType::AT_LSL_BYTECODE, true, true, 6500000); + s2.recordGetServiced(LLViewerAssetType::AT_LSL_BYTECODE, true, true, 10000); + + { + s2.merge(s1); + + LLSD src = s1.asLLSD(false); + LLSD dst = s2.asLLSD(false); + + ensure_equals("merge src has single region", src["regions"].size(), 1); + ensure_equals("merge dst has dual regions", dst["regions"].size(), 2); + + // Remove time stamps, they're a problem + src.erase("duration"); + src["regions"][0].erase("duration"); + dst.erase("duration"); + dst["regions"][0].erase("duration"); + dst["regions"][1].erase("duration"); + + LLSD s1_llsd = get_region(src, region1_handle); + ensure("Region1 is present in src", s1_llsd.isMap()); + LLSD s2_llsd = get_region(dst, region1_handle); + ensure("Region1 is present in dst", s2_llsd.isMap()); + + ensure("result from src is in dst", llsd_equals(s1_llsd, s2_llsd)); + } + + s1.setRegion(region1_handle); + s2.setRegion(region1_handle); + s1.reset(); + s2.reset(); + + s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + + s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + + s1.recordGetServiced(LLViewerAssetType::AT_LSL_BYTECODE, true, true, 23289200); + s1.recordGetServiced(LLViewerAssetType::AT_LSL_BYTECODE, true, true, 282900); + + + s2.setRegion(region1_handle); + s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + + s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + + s2.recordGetServiced(LLViewerAssetType::AT_LSL_BYTECODE, true, true, 6500000); + s2.recordGetServiced(LLViewerAssetType::AT_LSL_BYTECODE, true, true, 10000); + + { + s2.merge(s1); + + LLSD src = s1.asLLSD(false); + LLSD dst = s2.asLLSD(false); + + ensure_equals("merge src has single region (p2)", src["regions"].size(), 1); + ensure_equals("merge dst has single region (p2)", dst["regions"].size(), 1); + + // Remove time stamps, they're a problem + src.erase("duration"); + src["regions"][0].erase("duration"); + dst.erase("duration"); + dst["regions"][0].erase("duration"); + + LLSD s1_llsd = get_region(src, region1_handle); + ensure("Region1 is present in src", s1_llsd.isMap()); + LLSD s2_llsd = get_region(dst, region1_handle); + ensure("Region1 is present in dst", s2_llsd.isMap()); + + ensure_equals("src counts okay (enq)", s1_llsd["get_other"]["enqueued"].asInteger(), 4); + ensure_equals("src counts okay (deq)", s1_llsd["get_other"]["dequeued"].asInteger(), 4); + ensure_equals("src resp counts okay", s1_llsd["get_other"]["resp_count"].asInteger(), 2); + ensure_approximately_equals("src respmin okay", s1_llsd["get_other"]["resp_min"].asReal(), 0.2829, 20); + ensure_approximately_equals("src respmax okay", s1_llsd["get_other"]["resp_max"].asReal(), 23.2892, 20); + + ensure_equals("dst counts okay (enq)", s2_llsd["get_other"]["enqueued"].asInteger(), 12); + ensure_equals("src counts okay (deq)", s2_llsd["get_other"]["dequeued"].asInteger(), 11); + ensure_equals("dst resp counts okay", s2_llsd["get_other"]["resp_count"].asInteger(), 4); + ensure_approximately_equals("dst respmin okay", s2_llsd["get_other"]["resp_min"].asReal(), 0.010, 20); + ensure_approximately_equals("dst respmax okay", s2_llsd["get_other"]["resp_max"].asReal(), 23.2892, 20); + } + } + + + // Maximum merges are interesting when one side contributes nothing + template<> template<> + void tst_viewerassetstats_index_object_t::test<11>() + { + LLViewerAssetStats s1; + LLViewerAssetStats s2; + + s1.setRegion(region1_handle); + s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + + s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + + // Want to test negative numbers here but have to work in U64 + s1.recordGetServiced(LLViewerAssetType::AT_LSL_BYTECODE, true, true, 0); + s1.recordGetServiced(LLViewerAssetType::AT_LSL_BYTECODE, true, true, 0); + s1.recordGetServiced(LLViewerAssetType::AT_LSL_BYTECODE, true, true, 0); + + s2.setRegion(region1_handle); + s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + + s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + + { + s2.merge(s1); + + LLSD src = s1.asLLSD(false); + LLSD dst = s2.asLLSD(false); + + ensure_equals("merge src has single region", src["regions"].size(), 1); + ensure_equals("merge dst has single region", dst["regions"].size(), 1); + + // Remove time stamps, they're a problem + src.erase("duration"); + src["regions"][0].erase("duration"); + dst.erase("duration"); + dst["regions"][0].erase("duration"); + + LLSD s2_llsd = get_region(dst, region1_handle); + ensure("Region1 is present in dst", s2_llsd.isMap()); + + ensure_equals("dst counts come from src only", s2_llsd["get_other"]["resp_count"].asInteger(), 3); + + ensure_approximately_equals("dst maximum with count 0 does not contribute to merged maximum", + s2_llsd["get_other"]["resp_max"].asReal(), F64(0.0), 20); + } + + // Other way around + s1.setRegion(region1_handle); + s2.setRegion(region1_handle); + s1.reset(); + s2.reset(); + + s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + + s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + + // Want to test negative numbers here but have to work in U64 + s1.recordGetServiced(LLViewerAssetType::AT_LSL_BYTECODE, true, true, 0); + s1.recordGetServiced(LLViewerAssetType::AT_LSL_BYTECODE, true, true, 0); + s1.recordGetServiced(LLViewerAssetType::AT_LSL_BYTECODE, true, true, 0); + + s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + + s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + + { + s1.merge(s2); + + LLSD src = s2.asLLSD(false); + LLSD dst = s1.asLLSD(false); + + ensure_equals("merge src has single region", src["regions"].size(), 1); + ensure_equals("merge dst has single region", dst["regions"].size(), 1); + + // Remove time stamps, they're a problem + src.erase("duration"); + src["regions"][0].erase("duration"); + dst.erase("duration"); + dst["regions"][0].erase("duration"); + + LLSD s2_llsd = get_region(dst, region1_handle); + ensure("Region1 is present in dst", s2_llsd.isMap()); + + ensure_equals("dst counts come from src only (flipped)", s2_llsd["get_other"]["resp_count"].asInteger(), 3); + + ensure_approximately_equals("dst maximum with count 0 does not contribute to merged maximum (flipped)", + s2_llsd["get_other"]["resp_max"].asReal(), F64(0.0), 20); + } + } + + // Minimum merges are interesting when one side contributes nothing + template<> template<> + void tst_viewerassetstats_index_object_t::test<12>() + { + LLViewerAssetStats s1; + LLViewerAssetStats s2; + + s1.setRegion(region1_handle); + s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + + s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + + s1.recordGetServiced(LLViewerAssetType::AT_LSL_BYTECODE, true, true, 3800000); + s1.recordGetServiced(LLViewerAssetType::AT_LSL_BYTECODE, true, true, 2700000); + s1.recordGetServiced(LLViewerAssetType::AT_LSL_BYTECODE, true, true, 2900000); + + s2.setRegion(region1_handle); + s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + + s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + + { + s2.merge(s1); + + LLSD src = s1.asLLSD(false); + LLSD dst = s2.asLLSD(false); + + ensure_equals("merge src has single region", src["regions"].size(), 1); + ensure_equals("merge dst has single region", dst["regions"].size(), 1); + + // Remove time stamps, they're a problem + src.erase("duration"); + src["regions"][0].erase("duration"); + dst.erase("duration"); + dst["regions"][0].erase("duration"); + + LLSD s2_llsd = get_region(dst, region1_handle); + ensure("Region1 is present in dst", s2_llsd.isMap()); + + ensure_equals("dst counts come from src only", s2_llsd["get_other"]["resp_count"].asInteger(), 3); + + ensure_approximately_equals("dst minimum with count 0 does not contribute to merged minimum", + s2_llsd["get_other"]["resp_min"].asReal(), F64(2.7), 20); + } + + // Other way around + s1.setRegion(region1_handle); + s2.setRegion(region1_handle); + s1.reset(); + s2.reset(); + + s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + + s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + + s1.recordGetServiced(LLViewerAssetType::AT_LSL_BYTECODE, true, true, 3800000); + s1.recordGetServiced(LLViewerAssetType::AT_LSL_BYTECODE, true, true, 2700000); + s1.recordGetServiced(LLViewerAssetType::AT_LSL_BYTECODE, true, true, 2900000); + + s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + + s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); + + { + s1.merge(s2); + + LLSD src = s2.asLLSD(false); + LLSD dst = s1.asLLSD(false); + + ensure_equals("merge src has single region", src["regions"].size(), 1); + ensure_equals("merge dst has single region", dst["regions"].size(), 1); + + // Remove time stamps, they're a problem + src.erase("duration"); + src["regions"][0].erase("duration"); + dst.erase("duration"); + dst["regions"][0].erase("duration"); + + LLSD s2_llsd = get_region(dst, region1_handle); + ensure("Region1 is present in dst", s2_llsd.isMap()); + + ensure_equals("dst counts come from src only (flipped)", s2_llsd["get_other"]["resp_count"].asInteger(), 3); + + ensure_approximately_equals("dst minimum with count 0 does not contribute to merged minimum (flipped)", + s2_llsd["get_other"]["resp_min"].asReal(), F64(2.7), 20); + } + } + +} diff --git a/indra/newview/tests/llviewerhelputil_test.cpp b/indra/newview/tests/llviewerhelputil_test.cpp new file mode 100644 index 0000000000..710881d811 --- /dev/null +++ b/indra/newview/tests/llviewerhelputil_test.cpp @@ -0,0 +1,160 @@ +/** + * @file llviewerhelputil_test.cpp + * @brief LLViewerHelpUtil tests + * @author Tofu Linden + * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ +// Precompiled header +#include "../llviewerprecompiledheaders.h" + +#include "../test/lltut.h" + +#include "../llviewerhelputil.h" +#include "../llweb.h" +#include "llcontrol.h" + +#include <iostream> + +// values for all of the supported substitutions parameters +static std::string gHelpURL; +static std::string gVersion; +static std::string gChannel; +static std::string gLanguage; +static std::string gGrid; +static std::string gOS; + +//---------------------------------------------------------------------------- +// Mock objects for the dependencies of the code we're testing + +LLControlGroup::LLControlGroup(const std::string& name) + : LLInstanceTracker<LLControlGroup, std::string>(name) {} +LLControlGroup::~LLControlGroup() {} +BOOL LLControlGroup::declareString(const std::string& name, + const std::string& initial_val, + const std::string& comment, + BOOL persist) {return TRUE;} +void LLControlGroup::setString(const std::string& name, const std::string& val){} +std::string LLControlGroup::getString(const std::string& name) +{ + if (name == "HelpURLFormat") + return gHelpURL; + return ""; +} +LLControlGroup gSavedSettings("test"); + +static void substitute_string(std::string &input, const std::string &search, const std::string &replace) +{ + size_t pos = input.find(search); + while (pos != std::string::npos) + { + input = input.replace(pos, search.size(), replace); + pos = input.find(search); + } +} + +#include "../llagent.h" +LLAgent::LLAgent() : mAgentAccess(NULL) { } +LLAgent::~LLAgent() { } +bool LLAgent::isGodlike() const { return FALSE; } + +LLAgent gAgent; + +std::string LLWeb::expandURLSubstitutions(const std::string &url, + const LLSD &default_subs) +{ + (void)gAgent.isGodlike(); // ref symbol to stop compiler from stripping it + std::string new_url = url; + substitute_string(new_url, "[TOPIC]", default_subs["TOPIC"].asString()); + substitute_string(new_url, "[VERSION]", gVersion); + substitute_string(new_url, "[CHANNEL]", gChannel); + substitute_string(new_url, "[LANGUAGE]", gLanguage); + substitute_string(new_url, "[GRID]", gGrid); + substitute_string(new_url, "[OS]", gOS); + return new_url; +} + + +//---------------------------------------------------------------------------- + +namespace tut +{ + struct viewerhelputil + { + }; + + typedef test_group<viewerhelputil> viewerhelputil_t; + typedef viewerhelputil_t::object viewerhelputil_object_t; + tut::viewerhelputil_t tut_viewerhelputil("LLViewerHelpUtil"); + + template<> template<> + void viewerhelputil_object_t::test<1>() + { + std::string topic("test_topic"); + std::string subresult; + + gHelpURL = "fooformat"; + subresult = LLViewerHelpUtil::buildHelpURL(topic); + ensure_equals("no substitution tags", subresult, "fooformat"); + + gHelpURL = ""; + subresult = LLViewerHelpUtil::buildHelpURL(topic); + ensure_equals("blank substitution format", subresult, ""); + + gHelpURL = "[TOPIC]"; + subresult = LLViewerHelpUtil::buildHelpURL(topic); + ensure_equals("topic name", subresult, "test_topic"); + + gHelpURL = "[LANGUAGE]"; + gLanguage = ""; + subresult = LLViewerHelpUtil::buildHelpURL(topic); + ensure_equals("simple substitution with blank", subresult, ""); + + gHelpURL = "[LANGUAGE]"; + gLanguage = "Esperanto"; + subresult = LLViewerHelpUtil::buildHelpURL(topic); + ensure_equals("simple substitution", subresult, "Esperanto"); + + gHelpURL = "http://secondlife.com/[LANGUAGE]"; + gLanguage = "Gaelic"; + subresult = LLViewerHelpUtil::buildHelpURL(topic); + ensure_equals("simple substitution with url", subresult, "http://secondlife.com/Gaelic"); + + gHelpURL = "[XXX]"; + subresult = LLViewerHelpUtil::buildHelpURL(topic); + ensure_equals("unknown substitution", subresult, "[XXX]"); + + gHelpURL = "[LANGUAGE]/[LANGUAGE]"; + gLanguage = "Esperanto"; + subresult = LLViewerHelpUtil::buildHelpURL(topic); + ensure_equals("multiple substitution", subresult, "Esperanto/Esperanto"); + + gHelpURL = "http://[CHANNEL]/[VERSION]/[LANGUAGE]/[OS]/[GRID]/[XXX]"; + gChannel = "Second Life Test"; + gVersion = "2.0"; + gLanguage = "gaelic"; + gOS = "AmigaOS 2.1"; + gGrid = "mysim"; + subresult = LLViewerHelpUtil::buildHelpURL(topic); + ensure_equals("complex substitution", subresult, "http://Second Life Test/2.0/gaelic/AmigaOS 2.1/mysim/[XXX]"); + } +} diff --git a/indra/newview/tests/llviewernetwork_test.cpp b/indra/newview/tests/llviewernetwork_test.cpp new file mode 100644 index 0000000000..dd7761475e --- /dev/null +++ b/indra/newview/tests/llviewernetwork_test.cpp @@ -0,0 +1,581 @@ +/** + * @file llviewernetwork_test.cpp + * @author Roxie + * @date 2009-03-9 + * @brief Test the viewernetwork functionality + * + * $LicenseInfo:firstyear=2009&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ +#include "../llviewerprecompiledheaders.h" +#include "../llviewernetwork.h" +#include "../test/lltut.h" +#include "../../llxml/llcontrol.h" +#include "llfile.h" + +//---------------------------------------------------------------------------- +// Mock objects for the dependencies of the code we're testing + +LLControlGroup::LLControlGroup(const std::string& name) +: LLInstanceTracker<LLControlGroup, std::string>(name) {} +LLControlGroup::~LLControlGroup() {} +BOOL LLControlGroup::declareString(const std::string& name, + const std::string& initial_val, + const std::string& comment, + BOOL persist) {return TRUE;} +void LLControlGroup::setString(const std::string& name, const std::string& val){} + +std::string gCmdLineLoginURI; +std::string gCmdLineGridChoice; +std::string gCmdLineHelperURI; +std::string gLoginPage; +std::string gCurrentGrid; +std::string LLControlGroup::getString(const std::string& name) +{ + if (name == "CmdLineGridChoice") + return gCmdLineGridChoice; + else if (name == "CmdLineHelperURI") + return gCmdLineHelperURI; + else if (name == "LoginPage") + return gLoginPage; + else if (name == "CurrentGrid") + return gCurrentGrid; + return ""; +} + +LLSD LLControlGroup::getLLSD(const std::string& name) +{ + if (name == "CmdLineLoginURI") + { + if(!gCmdLineLoginURI.empty()) + { + return LLSD(gCmdLineLoginURI); + } + } + return LLSD(); +} + +LLPointer<LLControlVariable> LLControlGroup::getControl(const std::string& name) +{ + ctrl_name_table_t::iterator iter = mNameTable.find(name); + return iter == mNameTable.end() ? LLPointer<LLControlVariable>() : iter->second; +} + +LLControlGroup gSavedSettings("test"); + +const char *gSampleGridFile = "<llsd><map>" +"<key>grid1</key><map>" +" <key>favorite</key><integer>1</integer>" +" <key>helper_uri</key><string>https://helper1/helpers/</string>" +" <key>label</key><string>mylabel</string>" +" <key>login_page</key><string>loginpage</string>" +" <key>login_uri</key><array><string>myloginuri</string></array>" +" <key>name</key><string>grid1</string>" +" <key>visible</key><integer>1</integer>" +" <key>credential_type</key><string>agent</string>" +" <key>grid_login_id</key><string>MyGrid</string>" +"</map>" +"<key>util.agni.lindenlab.com</key><map>" +" <key>favorite</key><integer>1</integer>" +" <key>helper_uri</key><string>https://helper1/helpers/</string>" +" <key>label</key><string>mylabel</string>" +" <key>login_page</key><string>loginpage</string>" +" <key>login_uri</key><array><string>myloginuri</string></array>" +" <key>name</key><string>util.agni.lindenlab.com</string>" +"</map></map></llsd>"; +// ------------------------------------------------------------------------------------------- +// TUT +// ------------------------------------------------------------------------------------------- +namespace tut +{ + // Test wrapper declaration : wrapping nothing for the moment + struct viewerNetworkTest + { + viewerNetworkTest() + { + LLFile::remove("grid_test.xml"); + gCmdLineLoginURI.clear(); + gCmdLineGridChoice.clear(); + gCmdLineHelperURI.clear(); + gLoginPage.clear(); + gCurrentGrid.clear(); + } + ~viewerNetworkTest() + { + LLFile::remove("grid_test.xml"); + } + }; + + // Tut templating thingamagic: test group, object and test instance + typedef test_group<viewerNetworkTest> viewerNetworkTestFactory; + typedef viewerNetworkTestFactory::object viewerNetworkTestObject; + tut::viewerNetworkTestFactory tut_test("LLViewerNetwork"); + + // --------------------------------------------------------------------------------------- + // Test functions + // --------------------------------------------------------------------------------------- + // initialization without a grid file + template<> template<> + void viewerNetworkTestObject::test<1>() + { + + LLGridManager *manager = LLGridManager::getInstance(); + // grid file doesn't exist + manager->initialize("grid_test.xml"); + // validate that some of the defaults are available. + std::map<std::string, std::string> known_grids = manager->getKnownGrids(); + ensure_equals("Known grids is a string-string map of size 23", known_grids.size(), 23); + ensure_equals("Agni has the right name and label", + known_grids[std::string("util.agni.lindenlab.com")], std::string("Agni")); + ensure_equals("None exists", known_grids[""], "None"); + + LLSD grid; + LLGridManager::getInstance()->getGridInfo("util.agni.lindenlab.com", grid); + ensure("Grid info for agni is a map", grid.isMap()); + ensure_equals("name is correct for agni", + grid[GRID_VALUE].asString(), std::string("util.agni.lindenlab.com")); + ensure_equals("label is correct for agni", + grid[GRID_LABEL_VALUE].asString(), std::string("Agni")); + ensure("Login URI is an array", + grid[GRID_LOGIN_URI_VALUE].isArray()); + ensure_equals("Agni login uri is correct", + grid[GRID_LOGIN_URI_VALUE][0].asString(), + std::string("https://login.agni.lindenlab.com/cgi-bin/login.cgi")); + ensure_equals("Agni helper uri is correct", + grid[GRID_HELPER_URI_VALUE].asString(), + std::string("https://secondlife.com/helpers/")); + ensure_equals("Agni login page is correct", + grid[GRID_LOGIN_PAGE_VALUE].asString(), + std::string("http://secondlife.com/app/login/")); + ensure("Agni is a favorite", + grid.has(GRID_IS_FAVORITE_VALUE)); + ensure("Agni is a system grid", + grid.has(GRID_IS_SYSTEM_GRID_VALUE)); + ensure("Grid file wasn't greated as it wasn't saved", + !LLFile::isfile("grid_test.xml")); + } + + // initialization with a grid file + template<> template<> + void viewerNetworkTestObject::test<2>() + { + llofstream gridfile("grid_test.xml"); + gridfile << gSampleGridFile; + gridfile.close(); + + LLGridManager::getInstance()->initialize("grid_test.xml"); + std::map<std::string, std::string> known_grids = LLGridManager::getInstance()->getKnownGrids(); + ensure_equals("adding a grid via a grid file increases known grid size", + known_grids.size(), 24); + ensure_equals("Agni is still there after we've added a grid via a grid file", + known_grids["util.agni.lindenlab.com"], std::string("Agni")); + + + // assure Agni doesn't get overwritten + LLSD grid; + LLGridManager::getInstance()->getGridInfo("util.agni.lindenlab.com", grid); + + ensure_equals("Agni grid label was not modified by grid file", + grid[GRID_LABEL_VALUE].asString(), std::string("Agni")); + + ensure_equals("Agni name wasn't modified by grid file", + grid[GRID_VALUE].asString(), std::string("util.agni.lindenlab.com")); + ensure("Agni grid URI is still an array after grid file", + grid[GRID_LOGIN_URI_VALUE].isArray()); + ensure_equals("Agni login uri still the same after grid file", + grid[GRID_LOGIN_URI_VALUE][0].asString(), + std::string("https://login.agni.lindenlab.com/cgi-bin/login.cgi")); + ensure_equals("Agni helper uri still the same after grid file", + grid[GRID_HELPER_URI_VALUE].asString(), + std::string("https://secondlife.com/helpers/")); + ensure_equals("Agni login page the same after grid file", + grid[GRID_LOGIN_PAGE_VALUE].asString(), + std::string("http://secondlife.com/app/login/")); + ensure("Agni still a favorite after grid file", + grid.has(GRID_IS_FAVORITE_VALUE)); + ensure("Agni system grid still set after grid file", + grid.has(GRID_IS_SYSTEM_GRID_VALUE)); + + ensure_equals("Grid file adds to name<->label map", + known_grids["grid1"], std::string("mylabel")); + LLGridManager::getInstance()->getGridInfo("grid1", grid); + ensure_equals("grid file grid name is set", + grid[GRID_VALUE].asString(), std::string("grid1")); + ensure_equals("grid file label is set", + grid[GRID_LABEL_VALUE].asString(), std::string("mylabel")); + ensure("grid file login uri is an array", + grid[GRID_LOGIN_URI_VALUE].isArray()); + ensure_equals("grid file login uri is set", + grid[GRID_LOGIN_URI_VALUE][0].asString(), + std::string("myloginuri")); + ensure_equals("grid file helper uri is set", + grid[GRID_HELPER_URI_VALUE].asString(), + std::string("https://helper1/helpers/")); + ensure_equals("grid file login page is set", + grid[GRID_LOGIN_PAGE_VALUE].asString(), + std::string("loginpage")); + ensure("grid file favorite is set", + grid.has(GRID_IS_FAVORITE_VALUE)); + ensure("grid file isn't a system grid", + !grid.has(GRID_IS_SYSTEM_GRID_VALUE)); + ensure("Grid file still exists after loading", + LLFile::isfile("grid_test.xml")); + } + + // Initialize via command line + + template<> template<> + void viewerNetworkTestObject::test<3>() + { + // USE --grid command line + // initialize with a known grid + LLSD grid; + gCmdLineGridChoice = "Aditi"; + LLGridManager::getInstance()->initialize("grid_test.xml"); + // with single login uri specified. + std::map<std::string, std::string> known_grids = LLGridManager::getInstance()->getKnownGrids(); + ensure_equals("Using a known grid via command line doesn't increase number of known grids", + known_grids.size(), 23); + ensure_equals("getGridLabel", LLGridManager::getInstance()->getGridLabel(), std::string("Aditi")); + // initialize with a known grid in lowercase + gCmdLineGridChoice = "agni"; + LLGridManager::getInstance()->initialize("grid_test.xml"); + ensure_equals("getGridLabel", LLGridManager::getInstance()->getGridLabel(), std::string("Agni")); + + // now try a command line with a custom grid identifier + gCmdLineGridChoice = "mycustomgridchoice"; + LLGridManager::getInstance()->initialize("grid_test.xml"); + known_grids = LLGridManager::getInstance()->getKnownGrids(); + ensure_equals("adding a command line grid with custom name increases known grid size", + known_grids.size(), 24); + ensure_equals("Custom Command line grid is added to the list of grids", + known_grids["mycustomgridchoice"], std::string("mycustomgridchoice")); + LLGridManager::getInstance()->getGridInfo("mycustomgridchoice", grid); + ensure_equals("Custom Command line grid name is set", + grid[GRID_VALUE].asString(), std::string("mycustomgridchoice")); + ensure_equals("Custom Command line grid label is set", + grid[GRID_LABEL_VALUE].asString(), std::string("mycustomgridchoice")); + ensure("Custom Command line grid login uri is an array", + grid[GRID_LOGIN_URI_VALUE].isArray()); + ensure_equals("Custom Command line grid login uri is set", + grid[GRID_LOGIN_URI_VALUE][0].asString(), + std::string("https://mycustomgridchoice/cgi-bin/login.cgi")); + ensure_equals("Custom Command line grid helper uri is set", + grid[GRID_HELPER_URI_VALUE].asString(), + std::string("https://mycustomgridchoice/helpers/")); + ensure_equals("Custom Command line grid login page is set", + grid[GRID_LOGIN_PAGE_VALUE].asString(), + std::string("http://mycustomgridchoice/app/login/")); + } + + // validate override of login uri with cmd line + template<> template<> + void viewerNetworkTestObject::test<4>() + { + // Override with loginuri + // override known grid + LLSD grid; + gCmdLineGridChoice = "Aditi"; + gCmdLineLoginURI = "https://my.login.uri/cgi-bin/login.cgi"; + LLGridManager::getInstance()->initialize("grid_test.xml"); + std::map<std::string, std::string> known_grids = LLGridManager::getInstance()->getKnownGrids(); + ensure_equals("Override known grid login uri: No grids are added", + known_grids.size(), 23); + LLGridManager::getInstance()->getGridInfo(grid); + ensure("Override known grid login uri: login uri is an array", + grid[GRID_LOGIN_URI_VALUE].isArray()); + ensure_equals("Override known grid login uri: Command line grid login uri is set", + grid[GRID_LOGIN_URI_VALUE][0].asString(), + std::string("https://my.login.uri/cgi-bin/login.cgi")); + ensure_equals("Override known grid login uri: helper uri is not changed", + grid[GRID_HELPER_URI_VALUE].asString(), + std::string("http://aditi-secondlife.webdev.lindenlab.com/helpers/")); + ensure_equals("Override known grid login uri: login page is not set", + grid[GRID_LOGIN_PAGE_VALUE].asString(), + std::string("http://secondlife.com/app/login/")); + + // Override with loginuri + // override custom grid + gCmdLineGridChoice = "mycustomgridchoice"; + gCmdLineLoginURI = "https://my.login.uri/cgi-bin/login.cgi"; + LLGridManager::getInstance()->initialize("grid_test.xml"); + known_grids = LLGridManager::getInstance()->getKnownGrids(); + LLGridManager::getInstance()->getGridInfo(grid); + ensure_equals("Override custom grid login uri: Grid is added", + known_grids.size(), 24); + ensure("Override custom grid login uri: login uri is an array", + grid[GRID_LOGIN_URI_VALUE].isArray()); + ensure_equals("Override custom grid login uri: login uri is set", + grid[GRID_LOGIN_URI_VALUE][0].asString(), + std::string("https://my.login.uri/cgi-bin/login.cgi")); + ensure_equals("Override custom grid login uri: Helper uri is not set", + grid[GRID_HELPER_URI_VALUE].asString(), + std::string("https://mycustomgridchoice/helpers/")); + ensure_equals("Override custom grid login uri: Login page is not set", + grid[GRID_LOGIN_PAGE_VALUE].asString(), + std::string("http://mycustomgridchoice/app/login/")); + } + + // validate override of helper uri with cmd line + template<> template<> + void viewerNetworkTestObject::test<5>() + { + // Override with helperuri + // override known grid + LLSD grid; + gCmdLineGridChoice = "Aditi"; + gCmdLineLoginURI = ""; + gCmdLineHelperURI = "https://my.helper.uri/mycustomhelpers"; + LLGridManager::getInstance()->initialize("grid_test.xml"); + std::map<std::string, std::string> known_grids = LLGridManager::getInstance()->getKnownGrids(); + ensure_equals("Override known grid helper uri: No grids are added", + known_grids.size(), 23); + LLGridManager::getInstance()->getGridInfo(grid); + ensure("Override known known helper uri: login uri is an array", + grid[GRID_LOGIN_URI_VALUE].isArray()); + ensure_equals("Override known grid helper uri: login uri is not changed", + grid[GRID_LOGIN_URI_VALUE][0].asString(), + std::string("https://login.aditi.lindenlab.com/cgi-bin/login.cgi")); + ensure_equals("Override known grid helper uri: helper uri is changed", + grid[GRID_HELPER_URI_VALUE].asString(), + std::string("https://my.helper.uri/mycustomhelpers")); + ensure_equals("Override known grid helper uri: login page is not changed", + grid[GRID_LOGIN_PAGE_VALUE].asString(), + std::string("http://secondlife.com/app/login/")); + + // Override with helperuri + // override custom grid + gCmdLineGridChoice = "mycustomgridchoice"; + gCmdLineHelperURI = "https://my.helper.uri/mycustomhelpers"; + LLGridManager::getInstance()->initialize("grid_test.xml"); + known_grids = LLGridManager::getInstance()->getKnownGrids(); + ensure_equals("Override custom grid helper uri: grids is added", + known_grids.size(), 24); + LLGridManager::getInstance()->getGridInfo(grid); + ensure("Override custom helper uri: login uri is an array", + grid[GRID_LOGIN_URI_VALUE].isArray()); + ensure_equals("Override custom grid helper uri: login uri is not changed", + grid[GRID_LOGIN_URI_VALUE][0].asString(), + std::string("https://mycustomgridchoice/cgi-bin/login.cgi")); + ensure_equals("Override custom grid helper uri: helper uri is changed", + grid[GRID_HELPER_URI_VALUE].asString(), + std::string("https://my.helper.uri/mycustomhelpers")); + ensure_equals("Override custom grid helper uri: login page is not changed", + grid[GRID_LOGIN_PAGE_VALUE].asString(), + std::string("http://mycustomgridchoice/app/login/")); + } + + // validate overriding of login page via cmd line + template<> template<> + void viewerNetworkTestObject::test<6>() + { + // Override with login page + // override known grid + LLSD grid; + gCmdLineGridChoice = "Aditi"; + gCmdLineHelperURI = ""; + gLoginPage = "myloginpage"; + LLGridManager::getInstance()->initialize("grid_test.xml"); + std::map<std::string, std::string> known_grids = LLGridManager::getInstance()->getKnownGrids(); + ensure_equals("Override known grid login page: No grids are added", + known_grids.size(), 23); + LLGridManager::getInstance()->getGridInfo(grid); + ensure("Override known grid login page: Command line grid login uri is an array", + grid[GRID_LOGIN_URI_VALUE].isArray()); + ensure_equals("Override known grid login page: login uri is not changed", + grid[GRID_LOGIN_URI_VALUE][0].asString(), + std::string("https://login.aditi.lindenlab.com/cgi-bin/login.cgi")); + ensure_equals("Override known grid login page: helper uri is not changed", + grid[GRID_HELPER_URI_VALUE].asString(), + std::string("http://aditi-secondlife.webdev.lindenlab.com/helpers/")); + ensure_equals("Override known grid login page: login page is changed", + grid[GRID_LOGIN_PAGE_VALUE].asString(), + std::string("myloginpage")); + + // Override with login page + // override custom grid + gCmdLineGridChoice = "mycustomgridchoice"; + gLoginPage = "myloginpage"; + LLGridManager::getInstance()->initialize("grid_test.xml"); + known_grids = LLGridManager::getInstance()->getKnownGrids(); + ensure_equals("Override custom grid login page: grids are added", + known_grids.size(), 24); + LLGridManager::getInstance()->getGridInfo(grid); + ensure("Override custom grid login page: Command line grid login uri is an array", + grid[GRID_LOGIN_URI_VALUE].isArray()); + ensure_equals("Override custom grid login page: login uri is not changed", + grid[GRID_LOGIN_URI_VALUE][0].asString(), + std::string("https://mycustomgridchoice/cgi-bin/login.cgi")); + ensure_equals("Override custom grid login page: helper uri is not changed", + grid[GRID_HELPER_URI_VALUE].asString(), + std::string("https://mycustomgridchoice/helpers/")); + ensure_equals("Override custom grid login page: login page is changed", + grid[GRID_LOGIN_PAGE_VALUE].asString(), + std::string("myloginpage")); + + } + + // validate grid selection + template<> template<> + void viewerNetworkTestObject::test<7>() + { + LLSD loginURI = LLSD::emptyArray(); + LLSD grid = LLSD::emptyMap(); + // adding a grid with simply a name will populate the values. + grid[GRID_VALUE] = "myaddedgrid"; + + LLGridManager::getInstance()->initialize("grid_test.xml"); + LLGridManager::getInstance()->addGrid(grid); + LLGridManager::getInstance()->setGridChoice("util.agni.lindenlab.com"); + ensure_equals("getGridLabel", LLGridManager::getInstance()->getGridLabel(), std::string("Agni")); + ensure_equals("getGrid", LLGridManager::getInstance()->getGrid(), + std::string("util.agni.lindenlab.com")); + ensure_equals("getHelperURI", LLGridManager::getInstance()->getHelperURI(), + std::string("https://secondlife.com/helpers/")); + ensure_equals("getLoginPage", LLGridManager::getInstance()->getLoginPage(), + std::string("http://secondlife.com/app/login/")); + ensure_equals("getLoginPage2", LLGridManager::getInstance()->getLoginPage("util.agni.lindenlab.com"), + std::string("http://secondlife.com/app/login/")); + ensure("Is Agni a production grid", LLGridManager::getInstance()->isInProductionGrid()); + std::vector<std::string> uris; + LLGridManager::getInstance()->getLoginURIs(uris); + ensure_equals("getLoginURIs size", uris.size(), 1); + ensure_equals("getLoginURIs", uris[0], + std::string("https://login.agni.lindenlab.com/cgi-bin/login.cgi")); + LLGridManager::getInstance()->setGridChoice("myaddedgrid"); + ensure_equals("getGridLabel", LLGridManager::getInstance()->getGridLabel(), std::string("myaddedgrid")); + ensure("Is myaddedgrid a production grid", !LLGridManager::getInstance()->isInProductionGrid()); + + LLGridManager::getInstance()->setFavorite(); + LLGridManager::getInstance()->getGridInfo("myaddedgrid", grid); + ensure("setting favorite", grid.has(GRID_IS_FAVORITE_VALUE)); + } + + // name based grid population + template<> template<> + void viewerNetworkTestObject::test<8>() + { + LLGridManager::getInstance()->initialize("grid_test.xml"); + LLSD grid = LLSD::emptyMap(); + // adding a grid with simply a name will populate the values. + grid[GRID_VALUE] = "myaddedgrid"; + LLGridManager::getInstance()->addGrid(grid); + LLGridManager::getInstance()->getGridInfo("myaddedgrid", grid); + + ensure_equals("name based grid has name value", + grid[GRID_VALUE].asString(), + std::string("myaddedgrid")); + ensure_equals("name based grid has label value", + grid[GRID_LABEL_VALUE].asString(), + std::string("myaddedgrid")); + ensure_equals("name based grid has name value", + grid[GRID_HELPER_URI_VALUE].asString(), + std::string("https://myaddedgrid/helpers/")); + ensure_equals("name based grid has name value", + grid[GRID_LOGIN_PAGE_VALUE].asString(), + std::string("http://myaddedgrid/app/login/")); + ensure("name based grid has array loginuri", + grid[GRID_LOGIN_URI_VALUE].isArray()); + ensure_equals("name based grid has single login uri value", + grid[GRID_LOGIN_URI_VALUE].size(), 1); + ensure_equals("Name based grid login uri is correct", + grid[GRID_LOGIN_URI_VALUE][0].asString(), + std::string("https://myaddedgrid/cgi-bin/login.cgi")); + ensure("name based grid is not a favorite yet", + !grid.has(GRID_IS_FAVORITE_VALUE)); + ensure("name based grid does not have system setting", + !grid.has(GRID_IS_SYSTEM_GRID_VALUE)); + + llofstream gridfile("grid_test.xml"); + gridfile << gSampleGridFile; + gridfile.close(); + } + + // persistence of the grid list with an empty gridfile. + template<> template<> + void viewerNetworkTestObject::test<9>() + { + // try with initial grid list without a grid file, + // without setting the grid to a saveable favorite. + LLGridManager::getInstance()->initialize("grid_test.xml"); + LLSD grid = LLSD::emptyMap(); + grid[GRID_VALUE] = std::string("mynewgridname"); + LLGridManager::getInstance()->addGrid(grid); + LLGridManager::getInstance()->saveFavorites(); + ensure("Grid file exists after saving", + LLFile::isfile("grid_test.xml")); + LLGridManager::getInstance()->initialize("grid_test.xml"); + // should not be there + std::map<std::string, std::string> known_grids = LLGridManager::getInstance()->getKnownGrids(); + ensure("New grid wasn't added to persisted list without being marked a favorite", + known_grids.find(std::string("mynewgridname")) == known_grids.end()); + + // mark a grid a favorite to make sure it's persisted + LLGridManager::getInstance()->addGrid(grid); + LLGridManager::getInstance()->setGridChoice("mynewgridname"); + LLGridManager::getInstance()->setFavorite(); + LLGridManager::getInstance()->saveFavorites(); + ensure("Grid file exists after saving", + LLFile::isfile("grid_test.xml")); + LLGridManager::getInstance()->initialize("grid_test.xml"); + // should not be there + known_grids = LLGridManager::getInstance()->getKnownGrids(); + ensure("New grid wasn't added to persisted list after being marked a favorite", + known_grids.find(std::string("mynewgridname")) != + known_grids.end()); + } + + // persistence of the grid file with existing gridfile + template<> template<> + void viewerNetworkTestObject::test<10>() + { + + llofstream gridfile("grid_test.xml"); + gridfile << gSampleGridFile; + gridfile.close(); + + LLGridManager::getInstance()->initialize("grid_test.xml"); + LLSD grid = LLSD::emptyMap(); + grid[GRID_VALUE] = std::string("mynewgridname"); + LLGridManager::getInstance()->addGrid(grid); + LLGridManager::getInstance()->saveFavorites(); + // validate we didn't lose existing favorites + LLGridManager::getInstance()->initialize("grid_test.xml"); + std::map<std::string, std::string> known_grids = LLGridManager::getInstance()->getKnownGrids(); + ensure("New grid wasn't added to persisted list after being marked a favorite", + known_grids.find(std::string("grid1")) != + known_grids.end()); + + // add a grid + LLGridManager::getInstance()->addGrid(grid); + LLGridManager::getInstance()->setGridChoice("mynewgridname"); + LLGridManager::getInstance()->setFavorite(); + LLGridManager::getInstance()->saveFavorites(); + known_grids = LLGridManager::getInstance()->getKnownGrids(); + ensure("New grid wasn't added to persisted list after being marked a favorite", + known_grids.find(std::string("grid1")) != + known_grids.end()); + known_grids = LLGridManager::getInstance()->getKnownGrids(); + ensure("New grid wasn't added to persisted list after being marked a favorite", + known_grids.find(std::string("mynewgridname")) != + known_grids.end()); + } +} diff --git a/indra/newview/tests/llworldmap_test.cpp b/indra/newview/tests/llworldmap_test.cpp new file mode 100644 index 0000000000..acc6e814bc --- /dev/null +++ b/indra/newview/tests/llworldmap_test.cpp @@ -0,0 +1,515 @@ +/** + * @file llworldmap_test.cpp + * @author Merov Linden + * @date 2009-03-09 + * + * $LicenseInfo:firstyear=2006&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +// Dependencies +#include "linden_common.h" +#include "llapr.h" +#include "llsingleton.h" +#include "lltrans.h" +#include "lluistring.h" +#include "../llviewertexture.h" +#include "../llworldmapmessage.h" +// Class to test +#include "../llworldmap.h" +// Tut header +#include "../test/lltut.h" + +// ------------------------------------------------------------------------------------------- +// Stubbing: Declarations required to link and run the class being tested +// Notes: +// * Add here stubbed implementation of the few classes and methods used in the class to be tested +// * Add as little as possible (let the link errors guide you) +// * Do not make any assumption as to how those classes or methods work (i.e. don't copy/paste code) +// * A simulator for a class can be implemented here. Please comment and document thoroughly. + +// Stub image calls +void LLViewerTexture::setBoostLevel(S32 ) { } +void LLViewerTexture::setAddressMode(LLTexUnit::eTextureAddressMode ) { } +LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTexture(const LLUUID&, BOOL, LLViewerTexture::EBoostLevel, S8, + LLGLint, LLGLenum, LLHost ) { return NULL; } + +// Stub related map calls +LLWorldMapMessage::LLWorldMapMessage() { } +LLWorldMapMessage::~LLWorldMapMessage() { } +void LLWorldMapMessage::sendItemRequest(U32 type, U64 handle) { } +void LLWorldMapMessage::sendMapBlockRequest(U16 min_x, U16 min_y, U16 max_x, U16 max_y, bool return_nonexistent) { } + +LLWorldMipmap::LLWorldMipmap() { } +LLWorldMipmap::~LLWorldMipmap() { } +void LLWorldMipmap::reset() { } +void LLWorldMipmap::dropBoostLevels() { } +void LLWorldMipmap::equalizeBoostLevels() { } +LLPointer<LLViewerFetchedTexture> LLWorldMipmap::getObjectsTile(U32 grid_x, U32 grid_y, S32 level, bool load) { return NULL; } + +// Stub other stuff +std::string LLTrans::getString(const std::string &, const LLStringUtil::format_map_t& ) { return std::string("test_trans"); } +void LLUIString::updateResult() const { } +void LLUIString::setArg(const std::string& , const std::string& ) { } +void LLUIString::assign(const std::string& ) { } + +// End Stubbing +// ------------------------------------------------------------------------------------------- + +// ------------------------------------------------------------------------------------------- +// TUT +// ------------------------------------------------------------------------------------------- + +const F32 X_WORLD_TEST = 1000.0f * REGION_WIDTH_METERS; +const F32 Y_WORLD_TEST = 2000.0f * REGION_WIDTH_METERS; +const F32 Z_WORLD_TEST = 240.0f; +const std::string ITEM_NAME_TEST = "Item Foo"; +const std::string TOOLTIP_TEST = "Tooltip Foo"; + +const std::string SIM_NAME_TEST = "Sim Foo"; + +namespace tut +{ + // Test wrapper declarations + struct iteminfo_test + { + // Instance to be tested + LLItemInfo* mItem; + + // Constructor and destructor of the test wrapper + iteminfo_test() + { + LLUUID id; + mItem = new LLItemInfo(X_WORLD_TEST, Y_WORLD_TEST, ITEM_NAME_TEST, id); + } + ~iteminfo_test() + { + delete mItem; + } + }; + + struct siminfo_test + { + // Instance to be tested + LLSimInfo* mSim; + + // Constructor and destructor of the test wrapper + siminfo_test() + { + U64 handle = to_region_handle_global(X_WORLD_TEST, Y_WORLD_TEST); + mSim = new LLSimInfo(handle); + } + ~siminfo_test() + { + delete mSim; + } + }; + + struct worldmap_test + { + // Instance to be tested + LLWorldMap* mWorld; + + // Constructor and destructor of the test wrapper + worldmap_test() + { + mWorld = LLWorldMap::getInstance(); + } + ~worldmap_test() + { + mWorld = NULL; + } + }; + + // Tut templating thingamagic: test group, object and test instance + typedef test_group<iteminfo_test> iteminfo_t; + typedef iteminfo_t::object iteminfo_object_t; + tut::iteminfo_t tut_iteminfo("LLItemInfo"); + + typedef test_group<siminfo_test> siminfo_t; + typedef siminfo_t::object siminfo_object_t; + tut::siminfo_t tut_siminfo("LLSimInfo"); + + typedef test_group<worldmap_test> worldmap_t; + typedef worldmap_t::object worldmap_object_t; + tut::worldmap_t tut_worldmap("LLWorldMap"); + + // --------------------------------------------------------------------------------------- + // Test functions + // Notes: + // * Test as many as you possibly can without requiring a full blown simulation of everything + // * The tests are executed in sequence so the test instance state may change between calls + // * Remember that you cannot test private methods with tut + // --------------------------------------------------------------------------------------- + + // --------------------------------------------------------------------------------------- + // Test the LLItemInfo interface + // --------------------------------------------------------------------------------------- + template<> template<> + void iteminfo_object_t::test<1>() + { + // Test 1 : setCount() / getCount() + mItem->setCount(10); + ensure("LLItemInfo::setCount() test failed", mItem->getCount() == 10); + // Test 2 : setTooltip() / getToolTip() + std::string tooltip = TOOLTIP_TEST; + mItem->setTooltip(tooltip); + ensure("LLItemInfo::setTooltip() test failed", mItem->getToolTip() == TOOLTIP_TEST); + // Test 3 : setElevation() / getGlobalPosition() + mItem->setElevation(Z_WORLD_TEST); + LLVector3d pos = mItem->getGlobalPosition(); + LLVector3d ref(X_WORLD_TEST, Y_WORLD_TEST, Z_WORLD_TEST); + ensure("LLItemInfo::getGlobalPosition() test failed", pos == ref); + // Test 4 : getName() + std::string name = mItem->getName(); + ensure("LLItemInfo::getName() test failed", name == ITEM_NAME_TEST); + // Test 5 : isName() + ensure("LLItemInfo::isName() test failed", mItem->isName(name)); + // Test 6 : getUUID() + LLUUID id; + ensure("LLItemInfo::getUUID() test failed", mItem->getUUID() == id); + // Test 7 : getRegionHandle() + U64 handle = to_region_handle_global(X_WORLD_TEST, Y_WORLD_TEST); + ensure("LLItemInfo::getRegionHandle() test failed", mItem->getRegionHandle() == handle); + } + // --------------------------------------------------------------------------------------- + // Test the LLSimInfo interface + // --------------------------------------------------------------------------------------- + // Test Setters and Accessors methods + template<> template<> + void siminfo_object_t::test<1>() + { + // Test 1 : setName() / getName() + std::string name = SIM_NAME_TEST; + mSim->setName(name); + ensure("LLSimInfo::setName() test failed", mSim->getName() == SIM_NAME_TEST); + // Test 2 : isName() + ensure("LLSimInfo::isName() test failed", mSim->isName(name)); + // Test 3 : getGlobalPos() + LLVector3 local; + LLVector3d ref(X_WORLD_TEST, Y_WORLD_TEST, 0.0f); + LLVector3d pos = mSim->getGlobalPos(local); + ensure("LLSimInfo::getGlobalPos() test failed", pos == ref); + // Test 4 : getGlobalOrigin() + pos = mSim->getGlobalOrigin(); + ensure("LLSimInfo::getGlobalOrigin() test failed", pos == ref); + // Test 5 : clearImage() + try { + mSim->clearImage(); + } catch (...) { + fail("LLSimInfo::clearImage() test failed"); + } + // Test 6 : dropImagePriority() + try { + mSim->dropImagePriority(); + } catch (...) { + fail("LLSimInfo::dropImagePriority() test failed"); + } + // Test 7 : updateAgentCount() + try { + mSim->updateAgentCount(0.0f); + } catch (...) { + fail("LLSimInfo::updateAgentCount() test failed"); + } + // Test 8 : getAgentCount() + S32 agents = mSim->getAgentCount(); + ensure("LLSimInfo::getAgentCount() test failed", agents == 0); + // Test 9 : setLandForSaleImage() / getLandForSaleImage() + LLUUID id; + mSim->setLandForSaleImage(id); + LLPointer<LLViewerFetchedTexture> image = mSim->getLandForSaleImage(); + ensure("LLSimInfo::getLandForSaleImage() test failed", image.isNull()); + // Test 10 : isPG() + mSim->setAccess(SIM_ACCESS_PG); + ensure("LLSimInfo::isPG() test failed", mSim->isPG()); + // Test 11 : isDown() + mSim->setAccess(SIM_ACCESS_DOWN); + ensure("LLSimInfo::isDown() test failed", mSim->isDown()); + // Test 12 : Access strings can't be accessed from unit test... + //ensure("LLSimInfo::getAccessString() test failed", mSim->getAccessString() == "Offline"); + // Test 13 : Region strings can't be accessed from unit test... + //mSim->setRegionFlags(REGION_FLAGS_SANDBOX); + //ensure("LLSimInfo::setRegionFlags() test failed", mSim->getFlagsString() == "Sandbox"); + } + // Test management of LLInfoItem lists + template<> template<> + void siminfo_object_t::test<2>() + { + // Test 14 : clearItems() + try { + mSim->clearItems(); + } catch (...) { + fail("LLSimInfo::clearItems() at init test failed"); + } + + // Test 15 : Verify that all the lists are empty + LLSimInfo::item_info_list_t list; + list = mSim->getTeleHub(); + ensure("LLSimInfo::getTeleHub() empty at init test failed", list.empty()); + list = mSim->getInfoHub(); + ensure("LLSimInfo::getInfoHub() empty at init test failed", list.empty()); + list = mSim->getPGEvent(); + ensure("LLSimInfo::getPGEvent() empty at init test failed", list.empty()); + list = mSim->getMatureEvent(); + ensure("LLSimInfo::getMatureEvent() empty at init test failed", list.empty()); + list = mSim->getLandForSale(); + ensure("LLSimInfo::getLandForSale() empty at init test failed", list.empty()); + list = mSim->getAgentLocation(); + ensure("LLSimInfo::getAgentLocation() empty at init test failed", list.empty()); + + // Create an item to be inserted + LLUUID id; + LLItemInfo item(X_WORLD_TEST, Y_WORLD_TEST, ITEM_NAME_TEST, id); + + // Insert the item in each list + mSim->insertTeleHub(item); + mSim->insertInfoHub(item); + mSim->insertPGEvent(item); + mSim->insertMatureEvent(item); + mSim->insertLandForSale(item); + mSim->insertAgentLocation(item); + + // Test 16 : Verify that the lists contain 1 item each + list = mSim->getTeleHub(); + ensure("LLSimInfo::insertTeleHub() test failed", list.size() == 1); + list = mSim->getInfoHub(); + ensure("LLSimInfo::insertInfoHub() test failed", list.size() == 1); + list = mSim->getPGEvent(); + ensure("LLSimInfo::insertPGEvent() test failed", list.size() == 1); + list = mSim->getMatureEvent(); + ensure("LLSimInfo::insertMatureEvent() test failed", list.size() == 1); + list = mSim->getLandForSale(); + ensure("LLSimInfo::insertLandForSale() test failed", list.size() == 1); + list = mSim->getAgentLocation(); + ensure("LLSimInfo::insertAgentLocation() test failed", list.size() == 1); + + // Test 17 : clearItems() + try { + mSim->clearItems(); + } catch (...) { + fail("LLSimInfo::clearItems() at end test failed"); + } + + // Test 18 : Verify that all the lists are empty again... *except* agent which is persisted!! (on purpose) + list = mSim->getTeleHub(); + ensure("LLSimInfo::getTeleHub() empty after clear test failed", list.empty()); + list = mSim->getInfoHub(); + ensure("LLSimInfo::getInfoHub() empty after clear test failed", list.empty()); + list = mSim->getPGEvent(); + ensure("LLSimInfo::getPGEvent() empty after clear test failed", list.empty()); + list = mSim->getMatureEvent(); + ensure("LLSimInfo::getMatureEvent() empty after clear test failed", list.empty()); + list = mSim->getLandForSale(); + ensure("LLSimInfo::getLandForSale() empty after clear test failed", list.empty()); + list = mSim->getAgentLocation(); + ensure("LLSimInfo::getAgentLocation() empty after clear test failed", list.size() == 1); + } + + // --------------------------------------------------------------------------------------- + // Test the LLWorldMap interface + // --------------------------------------------------------------------------------------- + // Test Setters and Accessors methods + template<> template<> + void worldmap_object_t::test<1>() + { + // Test 1 : reset() + try { + mWorld->reset(); + } catch (...) { + fail("LLWorldMap::reset() at init test failed"); + } + // Test 2 : clearImageRefs() + try { + mWorld->clearImageRefs(); + } catch (...) { + fail("LLWorldMap::clearImageRefs() test failed"); + } + // Test 3 : dropImagePriorities() + try { + mWorld->dropImagePriorities(); + } catch (...) { + fail("LLWorldMap::dropImagePriorities() test failed"); + } + // Test 4 : reloadItems() + try { + mWorld->reloadItems(true); + } catch (...) { + fail("LLWorldMap::reloadItems() test failed"); + } + // Test 5 : updateRegions() + try { + mWorld->updateRegions(1000, 1000, 1004, 1004); + } catch (...) { + fail("LLWorldMap::updateRegions() test failed"); + } + // Test 6 : equalizeBoostLevels() + try { + mWorld->equalizeBoostLevels(); + } catch (...) { + fail("LLWorldMap::equalizeBoostLevels() test failed"); + } + // Test 7 : getObjectsTile() + try { + LLPointer<LLViewerFetchedTexture> image = mWorld->getObjectsTile((U32)(X_WORLD_TEST/REGION_WIDTH_METERS), (U32)(Y_WORLD_TEST/REGION_WIDTH_METERS), 1); + ensure("LLWorldMap::getObjectsTile() failed", image.isNull()); + } catch (...) { + fail("LLWorldMap::getObjectsTile() test failed with exception"); + } + } + // Test management of LLSimInfo lists + template<> template<> + void worldmap_object_t::test<2>() + { + // Test 8 : reset() + try { + mWorld->reset(); + } catch (...) { + fail("LLWorldMap::reset() at init test failed"); + } + + // Test 9 : Verify that all the region list is empty + LLWorldMap::sim_info_map_t list; + list = mWorld->getRegionMap(); + ensure("LLWorldMap::getRegionMap() empty at init test failed", list.empty()); + + // Test 10 : Insert a region + bool success; + LLUUID id; + std::string name_sim = SIM_NAME_TEST; + success = mWorld->insertRegion( U32(X_WORLD_TEST), + U32(Y_WORLD_TEST), + name_sim, + id, + SIM_ACCESS_PG, + REGION_FLAGS_SANDBOX); + list = mWorld->getRegionMap(); + ensure("LLWorldMap::insertRegion() failed", success && (list.size() == 1)); + + // Test 11 : Insert an item in the same region -> number of regions doesn't increase + std::string name_item = ITEM_NAME_TEST; + success = mWorld->insertItem( U32(X_WORLD_TEST + REGION_WIDTH_METERS/2), + U32(Y_WORLD_TEST + REGION_WIDTH_METERS/2), + name_item, + id, + MAP_ITEM_LAND_FOR_SALE, + 0, 0); + list = mWorld->getRegionMap(); + ensure("LLWorldMap::insertItem() in existing region failed", success && (list.size() == 1)); + + // Test 12 : Insert an item in another region -> number of regions increases + success = mWorld->insertItem( U32(X_WORLD_TEST + REGION_WIDTH_METERS*2), + U32(Y_WORLD_TEST + REGION_WIDTH_METERS*2), + name_item, + id, + MAP_ITEM_LAND_FOR_SALE, + 0, 0); + list = mWorld->getRegionMap(); + ensure("LLWorldMap::insertItem() in unexisting region failed", success && (list.size() == 2)); + + // Test 13 : simInfoFromPosGlobal() in region + LLVector3d pos1( X_WORLD_TEST + REGION_WIDTH_METERS*2 + REGION_WIDTH_METERS/2, + Y_WORLD_TEST + REGION_WIDTH_METERS*2 + REGION_WIDTH_METERS/2, + 0.0f); + LLSimInfo* sim; + sim = mWorld->simInfoFromPosGlobal(pos1); + ensure("LLWorldMap::simInfoFromPosGlobal() test on existing region failed", sim != NULL); + + // Test 14 : simInfoFromPosGlobal() outside region + LLVector3d pos2( X_WORLD_TEST + REGION_WIDTH_METERS*4 + REGION_WIDTH_METERS/2, + Y_WORLD_TEST + REGION_WIDTH_METERS*4 + REGION_WIDTH_METERS/2, + 0.0f); + sim = mWorld->simInfoFromPosGlobal(pos2); + ensure("LLWorldMap::simInfoFromPosGlobal() test outside region failed", sim == NULL); + + // Test 15 : simInfoFromName() + sim = mWorld->simInfoFromName(name_sim); + ensure("LLWorldMap::simInfoFromName() test on existing region failed", sim != NULL); + + // Test 16 : simInfoFromHandle() + U64 handle = to_region_handle_global(X_WORLD_TEST, Y_WORLD_TEST); + sim = mWorld->simInfoFromHandle(handle); + ensure("LLWorldMap::simInfoFromHandle() test on existing region failed", sim != NULL); + + // Test 17 : simNameFromPosGlobal() + LLVector3d pos3( X_WORLD_TEST + REGION_WIDTH_METERS/2, + Y_WORLD_TEST + REGION_WIDTH_METERS/2, + 0.0f); + success = mWorld->simNameFromPosGlobal(pos3, name_sim); + ensure("LLWorldMap::simNameFromPosGlobal() test on existing region failed", success && (name_sim == SIM_NAME_TEST)); + + // Test 18 : reset() + try { + mWorld->reset(); + } catch (...) { + fail("LLWorldMap::reset() at end test failed"); + } + + // Test 19 : Verify that all the region list is empty + list = mWorld->getRegionMap(); + ensure("LLWorldMap::getRegionMap() empty at end test failed", list.empty()); + } + // Test tracking + template<> template<> + void worldmap_object_t::test<3>() + { + // Point to track + LLVector3d pos( X_WORLD_TEST + REGION_WIDTH_METERS/2, Y_WORLD_TEST + REGION_WIDTH_METERS/2, Z_WORLD_TEST); + + // Test 20 : no tracking + mWorld->cancelTracking(); + ensure("LLWorldMap::cancelTracking() at begin test failed", mWorld->isTracking() == false); + + // Test 21 : set tracking + mWorld->setTracking(pos); + ensure("LLWorldMap::setTracking() failed", mWorld->isTracking() && !mWorld->isTrackingValidLocation()); + + // Test 22 : set click and commit flags + mWorld->setTrackingDoubleClick(); + ensure("LLWorldMap::setTrackingDoubleClick() failed", mWorld->isTrackingDoubleClick()); + mWorld->setTrackingCommit(); + ensure("LLWorldMap::setTrackingCommit() failed", mWorld->isTrackingCommit()); + + // Test 23 : in rectangle test + bool inRect = mWorld->isTrackingInRectangle( X_WORLD_TEST, Y_WORLD_TEST, + X_WORLD_TEST + REGION_WIDTH_METERS, + Y_WORLD_TEST + REGION_WIDTH_METERS); + ensure("LLWorldMap::isTrackingInRectangle() in rectangle failed", inRect); + inRect = mWorld->isTrackingInRectangle( X_WORLD_TEST + REGION_WIDTH_METERS, + Y_WORLD_TEST + REGION_WIDTH_METERS, + X_WORLD_TEST + 2 * REGION_WIDTH_METERS, + Y_WORLD_TEST + 2 * REGION_WIDTH_METERS); + ensure("LLWorldMap::isTrackingInRectangle() outside rectangle failed", !inRect); + + // Test 24 : set tracking to valid and invalid + mWorld->setTrackingValid(); + ensure("LLWorldMap::setTrackingValid() failed", mWorld->isTrackingValidLocation() && !mWorld->isTrackingInvalidLocation()); + mWorld->setTrackingInvalid(); + ensure("LLWorldMap::setTrackingInvalid() failed", !mWorld->isTrackingValidLocation() && mWorld->isTrackingInvalidLocation()); + + // Test 25 : getTrackedPositionGlobal() + LLVector3d res = mWorld->getTrackedPositionGlobal(); + ensure("LLWorldMap::getTrackedPositionGlobal() failed", res == pos); + + // Test 26 : reset tracking + mWorld->cancelTracking(); + ensure("LLWorldMap::cancelTracking() at end test failed", mWorld->isTracking() == false); + } +} diff --git a/indra/newview/tests/llworldmipmap_test.cpp b/indra/newview/tests/llworldmipmap_test.cpp new file mode 100644 index 0000000000..4c0959d1a9 --- /dev/null +++ b/indra/newview/tests/llworldmipmap_test.cpp @@ -0,0 +1,165 @@ +/** + * @file llworldmipmap_test.cpp + * @author Merov Linden + * @date 2009-02-03 + * + * $LicenseInfo:firstyear=2006&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +// Dependencies +#include "linden_common.h" +#include "../llviewertexture.h" +#include "../llviewercontrol.h" +// Class to test +#include "../llworldmipmap.h" +// Tut header +#include "../test/lltut.h" + +// ------------------------------------------------------------------------------------------- +// Stubbing: Declarations required to link and run the class being tested +// Notes: +// * Add here stubbed implementation of the few classes and methods used in the class to be tested +// * Add as little as possible (let the link errors guide you) +// * Do not make any assumption as to how those classes or methods work (i.e. don't copy/paste code) +// * A simulator for a class can be implemented here. Please comment and document thoroughly. + +void LLViewerTexture::setBoostLevel(S32 ) { } +LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTextureFromUrl(const std::string&, BOOL, LLViewerTexture::EBoostLevel, S8, + LLGLint, LLGLenum, const LLUUID& ) { return NULL; } + +LLControlGroup::LLControlGroup(const std::string& name) : LLInstanceTracker<LLControlGroup, std::string>(name) { } +LLControlGroup::~LLControlGroup() { } +std::string LLControlGroup::getString(const std::string& ) { return std::string("test_url"); } +LLControlGroup gSavedSettings("test_settings"); + +// End Stubbing +// ------------------------------------------------------------------------------------------- + +// ------------------------------------------------------------------------------------------- +// TUT +// ------------------------------------------------------------------------------------------- +namespace tut +{ + // Test wrapper declaration + struct worldmipmap_test + { + // Derived test class + class LLTestWorldMipmap : public LLWorldMipmap + { + // Put here stubbs of virtual methods we shouldn't call all the way down + }; + // Instance to be tested + LLTestWorldMipmap* mMap; + + // Constructor and destructor of the test wrapper + worldmipmap_test() + { + mMap = new LLTestWorldMipmap; + } + ~worldmipmap_test() + { + delete mMap; + } + }; + + // Tut templating thingamagic: test group, object and test instance + typedef test_group<worldmipmap_test> worldmipmap_t; + typedef worldmipmap_t::object worldmipmap_object_t; + tut::worldmipmap_t tut_worldmipmap("LLWorldMipmap"); + + // --------------------------------------------------------------------------------------- + // Test functions + // Notes: + // * Test as many as you possibly can without requiring a full blown simulation of everything + // * The tests are executed in sequence so the test instance state may change between calls + // * Remember that you cannot test private methods with tut + // --------------------------------------------------------------------------------------- + // Test static methods + // Test 1 : scaleToLevel() + template<> template<> + void worldmipmap_object_t::test<1>() + { + S32 level = mMap->scaleToLevel(0.0); + ensure("scaleToLevel() test 1 failed", level == LLWorldMipmap::MAP_LEVELS); + level = mMap->scaleToLevel(LLWorldMipmap::MAP_TILE_SIZE); + ensure("scaleToLevel() test 2 failed", level == 1); + level = mMap->scaleToLevel(10 * LLWorldMipmap::MAP_TILE_SIZE); + ensure("scaleToLevel() test 3 failed", level == 1); + } + // Test 2 : globalToMipmap() + template<> template<> + void worldmipmap_object_t::test<2>() + { + U32 grid_x, grid_y; + mMap->globalToMipmap(1000.f*REGION_WIDTH_METERS, 1000.f*REGION_WIDTH_METERS, 1, &grid_x, &grid_y); + ensure("globalToMipmap() test 1 failed", (grid_x == 1000) && (grid_y == 1000)); + mMap->globalToMipmap(0.0, 0.0, LLWorldMipmap::MAP_LEVELS, &grid_x, &grid_y); + ensure("globalToMipmap() test 2 failed", (grid_x == 0) && (grid_y == 0)); + } + // Test 3 : getObjectsTile() + template<> template<> + void worldmipmap_object_t::test<3>() + { + // Depends on some inline methods in LLViewerImage... Thinking about how to make this work + // LLPointer<LLViewerImage> img = mMap->getObjectsTile(0, 0, 1); + // ensure("getObjectsTile() test failed", img.isNull()); + } + // Test 4 : equalizeBoostLevels() + template<> template<> + void worldmipmap_object_t::test<4>() + { + try + { + mMap->equalizeBoostLevels(); + } + catch (...) + { + fail("equalizeBoostLevels() test failed"); + } + } + // Test 5 : dropBoostLevels() + template<> template<> + void worldmipmap_object_t::test<5>() + { + try + { + mMap->dropBoostLevels(); + } + catch (...) + { + fail("dropBoostLevels() test failed"); + } + } + // Test 6 : reset() + template<> template<> + void worldmipmap_object_t::test<6>() + { + try + { + mMap->reset(); + } + catch (...) + { + fail("reset() test failed"); + } + } +} diff --git a/indra/newview/tests/llxmlrpclistener_test.cpp b/indra/newview/tests/llxmlrpclistener_test.cpp new file mode 100644 index 0000000000..711c2a3d51 --- /dev/null +++ b/indra/newview/tests/llxmlrpclistener_test.cpp @@ -0,0 +1,250 @@ +/* + * @file llxmlrpclistener_test.cpp + * @author Nat Goodspeed + * @date 2009-03-20 + * @brief Test for llxmlrpclistener. + * + * $LicenseInfo:firstyear=2009&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +// Precompiled header +#include "../llviewerprecompiledheaders.h" +// associated header +#include "../llxmlrpclistener.h" +// STL headers +#include <iomanip> +// std headers +// external library headers +// other Linden headers +#include "../test/lltut.h" +#include "../llxmlrpctransaction.h" +#include "llevents.h" +#include "lleventfilter.h" +#include "llsd.h" +#include "llhost.h" +#include "llcontrol.h" +#include "tests/wrapllerrs.h" +#include "tests/commtest.h" + +LLControlGroup gSavedSettings("Global"); + +/***************************************************************************** +* TUT +*****************************************************************************/ +namespace tut +{ + struct data + { + data(): + pumps(LLEventPumps::instance()), + uri(std::string("http://") + + LLHost("127.0.0.1", commtest_data::getport("PORT")).getString()) + { + // These variables are required by machinery used by + // LLXMLRPCTransaction. The values reflect reality for this test + // executable; hopefully these values are correct. + gSavedSettings.declareBOOL("BrowserProxyEnabled", FALSE, "", FALSE); // don't persist + gSavedSettings.declareBOOL("NoVerifySSLCert", TRUE, "", FALSE); // don't persist + } + + // LLEventPump listener signature + bool captureReply(const LLSD& r) + { + reply = r; + return false; + } + + LLSD reply; + LLEventPumps& pumps; + std::string uri; + }; + typedef test_group<data> llxmlrpclistener_group; + typedef llxmlrpclistener_group::object object; + llxmlrpclistener_group llxmlrpclistenergrp("llxmlrpclistener"); + + template<> template<> + void object::test<1>() + { + set_test_name("request validation"); + WrapLL_ERRS capture; + LLSD request; + request["uri"] = uri; + std::string threw; + try + { + pumps.obtain("LLXMLRPCTransaction").post(request); + } + catch (const WrapLL_ERRS::FatalException& e) + { + threw = e.what(); + } + ensure_contains("threw exception", threw, "missing params"); + ensure_contains("identified missing", threw, "method"); + ensure_contains("identified missing", threw, "reply"); + } + + template<> template<> + void object::test<2>() + { + set_test_name("param types validation"); + WrapLL_ERRS capture; + LLSD request; + request["uri"] = uri; + request["method"] = "hello"; + request["reply"] = "reply"; + LLSD& params(request["params"]); + params["who"]["specifically"] = "world"; // LLXMLRPCListener only handles scalar params + std::string threw; + try + { + pumps.obtain("LLXMLRPCTransaction").post(request); + } + catch (const WrapLL_ERRS::FatalException& e) + { + threw = e.what(); + } + ensure_contains("threw exception", threw, "unknown type"); + } + + template<> template<> + void object::test<3>() + { + set_test_name("success case"); + LLSD request; + request["uri"] = uri; + request["method"] = "hello"; + request["reply"] = "reply"; + LLSD& params(request["params"]); + params["who"] = "world"; + // Set up a timeout filter so we don't spin forever waiting. + LLEventTimeout watchdog; + // Connect the timeout filter to the reply pump. + LLTempBoundListener temp( + pumps.obtain("reply"). + listen("watchdog", boost::bind(&LLEventTimeout::post, boost::ref(watchdog), _1))); + // Now connect our target listener to the timeout filter. + watchdog.listen("captureReply", boost::bind(&data::captureReply, this, _1)); + // Kick off the request... + reply.clear(); + pumps.obtain("LLXMLRPCTransaction").post(request); + // Set the timer + F32 timeout(10); + watchdog.eventAfter(timeout, LLSD().with("timeout", 0)); + // and pump "mainloop" until we get something, whether from + // LLXMLRPCListener or from the watchdog filter. + LLTimer timer; + F32 start = timer.getElapsedTimeF32(); + LLEventPump& mainloop(pumps.obtain("mainloop")); + while (reply.isUndefined()) + { + mainloop.post(LLSD()); + } + ensure("timeout works", (timer.getElapsedTimeF32() - start) < (timeout + 1)); + ensure_equals(reply["responses"]["hi_there"].asString(), "Hello, world!"); + } + + template<> template<> + void object::test<4>() + { + set_test_name("bogus method"); + LLSD request; + request["uri"] = uri; + request["method"] = "goodbye"; + request["reply"] = "reply"; + LLSD& params(request["params"]); + params["who"] = "world"; + // Set up a timeout filter so we don't spin forever waiting. + LLEventTimeout watchdog; + // Connect the timeout filter to the reply pump. + LLTempBoundListener temp( + pumps.obtain("reply"). + listen("watchdog", boost::bind(&LLEventTimeout::post, boost::ref(watchdog), _1))); + // Now connect our target listener to the timeout filter. + watchdog.listen("captureReply", boost::bind(&data::captureReply, this, _1)); + // Kick off the request... + reply.clear(); + pumps.obtain("LLXMLRPCTransaction").post(request); + // Set the timer + F32 timeout(10); + watchdog.eventAfter(timeout, LLSD().with("timeout", 0)); + // and pump "mainloop" until we get something, whether from + // LLXMLRPCListener or from the watchdog filter. + LLTimer timer; + F32 start = timer.getElapsedTimeF32(); + LLEventPump& mainloop(pumps.obtain("mainloop")); + while (reply.isUndefined()) + { + mainloop.post(LLSD()); + } + ensure("timeout works", (timer.getElapsedTimeF32() - start) < (timeout + 1)); + ensure_equals("XMLRPC error", reply["status"].asString(), "XMLRPCError"); + } + + template<> template<> + void object::test<5>() + { + set_test_name("bad type"); + LLSD request; + request["uri"] = uri; + request["method"] = "getdict"; + request["reply"] = "reply"; + (void)request["params"]; + // Set up a timeout filter so we don't spin forever waiting. + LLEventTimeout watchdog; + // Connect the timeout filter to the reply pump. + LLTempBoundListener temp( + pumps.obtain("reply"). + listen("watchdog", boost::bind(&LLEventTimeout::post, boost::ref(watchdog), _1))); + // Now connect our target listener to the timeout filter. + watchdog.listen("captureReply", boost::bind(&data::captureReply, this, _1)); + // Kick off the request... + reply.clear(); + pumps.obtain("LLXMLRPCTransaction").post(request); + // Set the timer + F32 timeout(10); + watchdog.eventAfter(timeout, LLSD().with("timeout", 0)); + // and pump "mainloop" until we get something, whether from + // LLXMLRPCListener or from the watchdog filter. + LLTimer timer; + F32 start = timer.getElapsedTimeF32(); + LLEventPump& mainloop(pumps.obtain("mainloop")); + while (reply.isUndefined()) + { + mainloop.post(LLSD()); + } + ensure("timeout works", (timer.getElapsedTimeF32() - start) < (timeout + 1)); + ensure_equals(reply["status"].asString(), "BadType"); + ensure_contains("bad type", reply["responses"]["nested_dict"].asString(), "bad XMLRPC type"); + } +} // namespace tut + +/***************************************************************************** +* Resolve link errors: use real machinery here, since we intend to exchange +* actual XML with a peer process. +*****************************************************************************/ +// Including llxmlrpctransaction.cpp drags in the static LLXMLRPCListener +// instantiated there. That's why it works to post requests to the LLEventPump +// named "LLXMLRPCTransaction". +#include "../llxmlrpctransaction.cpp" +#include "llcontrol.cpp" +#include "llxmltree.cpp" +#include "llxmlparser.cpp" diff --git a/indra/newview/tests/test_llxmlrpc_peer.py b/indra/newview/tests/test_llxmlrpc_peer.py new file mode 100644 index 0000000000..281b72a058 --- /dev/null +++ b/indra/newview/tests/test_llxmlrpc_peer.py @@ -0,0 +1,81 @@ +#!/usr/bin/env python +"""\ +@file test_llxmlrpc_peer.py +@author Nat Goodspeed +@date 2008-10-09 +@brief This script asynchronously runs the executable (with args) specified on + the command line, returning its result code. While that executable is + running, we provide dummy local services for use by C++ tests. + +$LicenseInfo:firstyear=2008&license=viewerlgpl$ +Second Life Viewer Source Code +Copyright (C) 2010, Linden Research, Inc. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; +version 2.1 of the License only. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA +$/LicenseInfo$ +""" + +import os +import sys +from threading import Thread +from SimpleXMLRPCServer import SimpleXMLRPCServer + +mydir = os.path.dirname(__file__) # expected to be .../indra/newview/tests/ +sys.path.insert(0, os.path.join(mydir, os.pardir, os.pardir, "lib", "python")) +sys.path.insert(1, os.path.join(mydir, os.pardir, os.pardir, "llmessage", "tests")) +from testrunner import freeport, run, debug + +class TestServer(SimpleXMLRPCServer): + def _dispatch(self, method, params): + try: + func = getattr(self, method) + except AttributeError: + raise Exception('method "%s" is not supported' % method) + else: + # LLXMLRPCListener constructs XMLRPC parameters that arrive as a + # 1-tuple containing a dict. + return func(**(params[0])) + + def hello(self, who): + # LLXMLRPCListener expects a dict return. + return {"hi_there": "Hello, %s!" % who} + + def getdict(self): + return dict(nested_dict=dict(a=17, b=5)) + + def log_request(self, code, size=None): + # For present purposes, we don't want the request splattered onto + # stderr, as it would upset devs watching the test run + pass + + def log_error(self, format, *args): + # Suppress error output as well + pass + +if __name__ == "__main__": + # Instantiate a TestServer on the first free port in the specified port + # range. Doing this inline is better than in a daemon thread: if it blows + # up here, we'll get a traceback. If it blew up in some other thread, the + # traceback would get eaten and we'd run the subject test program anyway. + xmlrpcd, port = freeport(xrange(8000, 8020), + lambda port: TestServer(('127.0.0.1', port))) + # Pass the selected port number to the subject test program via the + # environment. We don't want to impose requirements on the test program's + # command-line parsing -- and anyway, for C++ integration tests, that's + # performed in TUT code rather than our own. + os.environ["PORT"] = str(port) + sys.exit(run(server=Thread(name="xmlrpc", target=xmlrpcd.serve_forever), *sys.argv[1:])) |