tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

serialization.spec.ts (14178B)


      1 export const description = `Unit tests for data cache serialization`;
      2 
      3 import { getIsBuildingDataCache, setIsBuildingDataCache } from '../common/framework/data_cache.js';
      4 import { makeTestGroup } from '../common/internal/test_group.js';
      5 import { objectEquals } from '../common/util/util.js';
      6 import {
      7  deserializeExpectation,
      8  serializeExpectation,
      9 } from '../webgpu/shader/execution/expression/case_cache.js';
     10 import BinaryStream from '../webgpu/util/binary_stream.js';
     11 import {
     12  anyOf,
     13  deserializeComparator,
     14  serializeComparator,
     15  skipUndefined,
     16 } from '../webgpu/util/compare.js';
     17 import { kValue } from '../webgpu/util/constants.js';
     18 import {
     19  abstractFloat,
     20  abstractInt,
     21  bool,
     22  deserializeValue,
     23  f16,
     24  f32,
     25  i16,
     26  i32,
     27  i8,
     28  serializeValue,
     29  toMatrix,
     30  u16,
     31  u32,
     32  u8,
     33  vec2,
     34  vec3,
     35  vec4,
     36 } from '../webgpu/util/conversion.js';
     37 import { deserializeFPInterval, FP, serializeFPInterval } from '../webgpu/util/floating_point.js';
     38 
     39 import { UnitTest } from './unit_test.js';
     40 
     41 export const g = makeTestGroup(UnitTest);
     42 
     43 g.test('value').fn(t => {
     44  for (const value of [
     45    u32(kValue.u32.min + 0),
     46    u32(kValue.u32.min + 1),
     47    u32(kValue.u32.min + 2),
     48    u32(kValue.u32.max - 2),
     49    u32(kValue.u32.max - 1),
     50    u32(kValue.u32.max - 0),
     51 
     52    u16(kValue.u16.min + 0),
     53    u16(kValue.u16.min + 1),
     54    u16(kValue.u16.min + 2),
     55    u16(kValue.u16.max - 2),
     56    u16(kValue.u16.max - 1),
     57    u16(kValue.u16.max - 0),
     58 
     59    u8(kValue.u8.min + 0),
     60    u8(kValue.u8.min + 1),
     61    u8(kValue.u8.min + 2),
     62    u8(kValue.u8.max - 2),
     63    u8(kValue.u8.max - 1),
     64    u8(kValue.u8.max - 0),
     65 
     66    abstractInt(kValue.i64.negative.min),
     67    abstractInt(kValue.i64.negative.min + 1n),
     68    abstractInt(kValue.i64.negative.min + 2n),
     69    abstractInt(kValue.i64.negative.max - 2n),
     70    abstractInt(kValue.i64.negative.max - 1n),
     71    abstractInt(kValue.i64.positive.min),
     72    abstractInt(kValue.i64.positive.min + 1n),
     73    abstractInt(kValue.i64.positive.min + 2n),
     74    abstractInt(kValue.i64.positive.max - 2n),
     75    abstractInt(kValue.i64.positive.max - 1n),
     76    abstractInt(kValue.i64.positive.max),
     77 
     78    i32(kValue.i32.negative.min + 0),
     79    i32(kValue.i32.negative.min + 1),
     80    i32(kValue.i32.negative.min + 2),
     81    i32(kValue.i32.negative.max - 2),
     82    i32(kValue.i32.negative.max - 1),
     83    i32(kValue.i32.positive.min - 0),
     84    i32(kValue.i32.positive.min + 1),
     85    i32(kValue.i32.positive.min + 2),
     86    i32(kValue.i32.positive.max - 2),
     87    i32(kValue.i32.positive.max - 1),
     88    i32(kValue.i32.positive.max - 0),
     89 
     90    i16(kValue.i16.negative.min + 0),
     91    i16(kValue.i16.negative.min + 1),
     92    i16(kValue.i16.negative.min + 2),
     93    i16(kValue.i16.negative.max - 2),
     94    i16(kValue.i16.negative.max - 1),
     95    i16(kValue.i16.positive.min + 0),
     96    i16(kValue.i16.positive.min + 1),
     97    i16(kValue.i16.positive.min + 2),
     98    i16(kValue.i16.positive.max - 2),
     99    i16(kValue.i16.positive.max - 1),
    100    i16(kValue.i16.positive.max - 0),
    101 
    102    i8(kValue.i8.negative.min + 0),
    103    i8(kValue.i8.negative.min + 1),
    104    i8(kValue.i8.negative.min + 2),
    105    i8(kValue.i8.negative.max - 2),
    106    i8(kValue.i8.negative.max - 1),
    107    i8(kValue.i8.positive.min + 0),
    108    i8(kValue.i8.positive.min + 1),
    109    i8(kValue.i8.positive.min + 2),
    110    i8(kValue.i8.positive.max - 2),
    111    i8(kValue.i8.positive.max - 1),
    112    i8(kValue.i8.positive.max - 0),
    113 
    114    abstractFloat(0),
    115    abstractFloat(-0),
    116    abstractFloat(1),
    117    abstractFloat(-1),
    118    abstractFloat(0.5),
    119    abstractFloat(-0.5),
    120    abstractFloat(kValue.f64.positive.max),
    121    abstractFloat(kValue.f64.positive.min),
    122    abstractFloat(kValue.f64.positive.subnormal.max),
    123    abstractFloat(kValue.f64.positive.subnormal.min),
    124    abstractFloat(kValue.f64.negative.subnormal.max),
    125    abstractFloat(kValue.f64.negative.subnormal.min),
    126    abstractFloat(kValue.f64.positive.infinity),
    127    abstractFloat(kValue.f64.negative.infinity),
    128 
    129    f32(0),
    130    f32(-0),
    131    f32(1),
    132    f32(-1),
    133    f32(0.5),
    134    f32(-0.5),
    135    f32(kValue.f32.positive.max),
    136    f32(kValue.f32.positive.min),
    137    f32(kValue.f32.positive.subnormal.max),
    138    f32(kValue.f32.positive.subnormal.min),
    139    f32(kValue.f32.negative.subnormal.max),
    140    f32(kValue.f32.negative.subnormal.min),
    141    f32(kValue.f32.positive.infinity),
    142    f32(kValue.f32.negative.infinity),
    143 
    144    f16(0),
    145    f16(-0),
    146    f16(1),
    147    f16(-1),
    148    f16(0.5),
    149    f16(-0.5),
    150    f16(kValue.f16.positive.max),
    151    f16(kValue.f16.positive.min),
    152    f16(kValue.f16.positive.subnormal.max),
    153    f16(kValue.f16.positive.subnormal.min),
    154    f16(kValue.f16.negative.subnormal.max),
    155    f16(kValue.f16.negative.subnormal.min),
    156    f16(kValue.f16.positive.infinity),
    157    f16(kValue.f16.negative.infinity),
    158 
    159    bool(true),
    160    bool(false),
    161 
    162    vec2(f32(1), f32(2)),
    163    vec3(u32(1), u32(2), u32(3)),
    164    vec4(bool(false), bool(true), bool(false), bool(true)),
    165 
    166    toMatrix(
    167      [
    168        [0.0, 1.0],
    169        [2.0, 3.0],
    170      ],
    171      abstractFloat
    172    ),
    173    toMatrix(
    174      [
    175        [0.0, 1.0],
    176        [2.0, 3.0],
    177      ],
    178      f32
    179    ),
    180    toMatrix(
    181      [
    182        [0.0, 1.0, 2.0],
    183        [3.0, 4.0, 5.0],
    184      ],
    185      f16
    186    ),
    187    toMatrix(
    188      [
    189        [0.0, 1.0, 2.0, 3.0],
    190        [4.0, 5.0, 6.0, 7.0],
    191      ],
    192      abstractFloat
    193    ),
    194    toMatrix(
    195      [
    196        [0.0, 1.0, 2.0, 3.0],
    197        [4.0, 5.0, 6.0, 7.0],
    198      ],
    199      f32
    200    ),
    201    toMatrix(
    202      [
    203        [0.0, 1.0],
    204        [2.0, 3.0],
    205        [4.0, 5.0],
    206      ],
    207      f16
    208    ),
    209    toMatrix(
    210      [
    211        [0.0, 1.0, 2.0],
    212        [3.0, 4.0, 5.0],
    213        [6.0, 7.0, 8.0],
    214      ],
    215      abstractFloat
    216    ),
    217    toMatrix(
    218      [
    219        [0.0, 1.0, 2.0],
    220        [3.0, 4.0, 5.0],
    221        [6.0, 7.0, 8.0],
    222      ],
    223      f32
    224    ),
    225    toMatrix(
    226      [
    227        [0.0, 1.0, 2.0, 3.0],
    228        [4.0, 5.0, 6.0, 7.0],
    229        [8.0, 9.0, 10.0, 11.0],
    230      ],
    231      f16
    232    ),
    233    toMatrix(
    234      [
    235        [0.0, 1.0],
    236        [2.0, 3.0],
    237        [4.0, 5.0],
    238        [6.0, 7.0],
    239      ],
    240      abstractFloat
    241    ),
    242    toMatrix(
    243      [
    244        [0.0, 1.0],
    245        [2.0, 3.0],
    246        [4.0, 5.0],
    247        [6.0, 7.0],
    248      ],
    249      f32
    250    ),
    251    toMatrix(
    252      [
    253        [0.0, 1.0, 2.0],
    254        [3.0, 4.0, 5.0],
    255        [6.0, 7.0, 8.0],
    256        [9.0, 10.0, 11.0],
    257      ],
    258      f16
    259    ),
    260    toMatrix(
    261      [
    262        [0.0, 1.0, 2.0, 3.0],
    263        [4.0, 5.0, 6.0, 7.0],
    264        [8.0, 9.0, 10.0, 11.0],
    265        [12.0, 13.0, 14.0, 15.0],
    266      ],
    267      abstractFloat
    268    ),
    269    toMatrix(
    270      [
    271        [0.0, 1.0, 2.0, 3.0],
    272        [4.0, 5.0, 6.0, 7.0],
    273        [8.0, 9.0, 10.0, 11.0],
    274        [12.0, 13.0, 14.0, 15.0],
    275      ],
    276      f32
    277    ),
    278  ]) {
    279    const s = new BinaryStream(new Uint8Array(1024).buffer);
    280    serializeValue(s, value);
    281    const d = new BinaryStream(s.buffer().buffer);
    282    const deserialized = deserializeValue(d);
    283    t.expect(
    284      objectEquals(value, deserialized),
    285      `${value.type} ${value} -> serialize -> deserialize -> ${deserialized}
    286 buffer: ${s.buffer()}`
    287    );
    288  }
    289 });
    290 
    291 g.test('fpinterval_f32').fn(t => {
    292  for (const interval of [
    293    FP.f32.toInterval(0),
    294    FP.f32.toInterval(-0),
    295    FP.f32.toInterval(1),
    296    FP.f32.toInterval(-1),
    297    FP.f32.toInterval(0.5),
    298    FP.f32.toInterval(-0.5),
    299    FP.f32.toInterval(kValue.f32.positive.max),
    300    FP.f32.toInterval(kValue.f32.positive.min),
    301    FP.f32.toInterval(kValue.f32.positive.subnormal.max),
    302    FP.f32.toInterval(kValue.f32.positive.subnormal.min),
    303    FP.f32.toInterval(kValue.f32.negative.subnormal.max),
    304    FP.f32.toInterval(kValue.f32.negative.subnormal.min),
    305    FP.f32.toInterval(kValue.f32.positive.infinity),
    306    FP.f32.toInterval(kValue.f32.negative.infinity),
    307 
    308    FP.f32.toInterval([-0, 0]),
    309    FP.f32.toInterval([-1, 1]),
    310    FP.f32.toInterval([-0.5, 0.5]),
    311    FP.f32.toInterval([kValue.f32.positive.min, kValue.f32.positive.max]),
    312    FP.f32.toInterval([kValue.f32.positive.subnormal.min, kValue.f32.positive.subnormal.max]),
    313    FP.f32.toInterval([kValue.f32.negative.subnormal.min, kValue.f32.negative.subnormal.max]),
    314    FP.f32.toInterval([kValue.f32.negative.infinity, kValue.f32.positive.infinity]),
    315  ]) {
    316    const s = new BinaryStream(new Uint8Array(1024).buffer);
    317    serializeFPInterval(s, interval);
    318    const d = new BinaryStream(s.buffer().buffer);
    319    const deserialized = deserializeFPInterval(d);
    320    t.expect(
    321      objectEquals(interval, deserialized),
    322      `interval ${interval} -> serialize -> deserialize -> ${deserialized}`
    323    );
    324  }
    325 });
    326 
    327 g.test('fpinterval_f16').fn(t => {
    328  for (const interval of [
    329    FP.f16.toInterval(0),
    330    FP.f16.toInterval(-0),
    331    FP.f16.toInterval(1),
    332    FP.f16.toInterval(-1),
    333    FP.f16.toInterval(0.5),
    334    FP.f16.toInterval(-0.5),
    335    FP.f16.toInterval(kValue.f16.positive.max),
    336    FP.f16.toInterval(kValue.f16.positive.min),
    337    FP.f16.toInterval(kValue.f16.positive.subnormal.max),
    338    FP.f16.toInterval(kValue.f16.positive.subnormal.min),
    339    FP.f16.toInterval(kValue.f16.negative.subnormal.max),
    340    FP.f16.toInterval(kValue.f16.negative.subnormal.min),
    341    FP.f16.toInterval(kValue.f16.positive.infinity),
    342    FP.f16.toInterval(kValue.f16.negative.infinity),
    343 
    344    FP.f16.toInterval([-0, 0]),
    345    FP.f16.toInterval([-1, 1]),
    346    FP.f16.toInterval([-0.5, 0.5]),
    347    FP.f16.toInterval([kValue.f16.positive.min, kValue.f16.positive.max]),
    348    FP.f16.toInterval([kValue.f16.positive.subnormal.min, kValue.f16.positive.subnormal.max]),
    349    FP.f16.toInterval([kValue.f16.negative.subnormal.min, kValue.f16.negative.subnormal.max]),
    350    FP.f16.toInterval([kValue.f16.negative.infinity, kValue.f16.positive.infinity]),
    351  ]) {
    352    const s = new BinaryStream(new Uint8Array(1024).buffer);
    353    serializeFPInterval(s, interval);
    354    const d = new BinaryStream(s.buffer().buffer);
    355    const deserialized = deserializeFPInterval(d);
    356    t.expect(
    357      objectEquals(interval, deserialized),
    358      `interval ${interval} -> serialize -> deserialize -> ${deserialized}`
    359    );
    360  }
    361 });
    362 
    363 g.test('fpinterval_abstract').fn(t => {
    364  for (const interval of [
    365    FP.abstract.toInterval(0),
    366    FP.abstract.toInterval(-0),
    367    FP.abstract.toInterval(1),
    368    FP.abstract.toInterval(-1),
    369    FP.abstract.toInterval(0.5),
    370    FP.abstract.toInterval(-0.5),
    371    FP.abstract.toInterval(kValue.f64.positive.max),
    372    FP.abstract.toInterval(kValue.f64.positive.min),
    373    FP.abstract.toInterval(kValue.f64.positive.subnormal.max),
    374    FP.abstract.toInterval(kValue.f64.positive.subnormal.min),
    375    FP.abstract.toInterval(kValue.f64.negative.subnormal.max),
    376    FP.abstract.toInterval(kValue.f64.negative.subnormal.min),
    377    FP.abstract.toInterval(kValue.f64.positive.infinity),
    378    FP.abstract.toInterval(kValue.f64.negative.infinity),
    379 
    380    FP.abstract.toInterval([-0, 0]),
    381    FP.abstract.toInterval([-1, 1]),
    382    FP.abstract.toInterval([-0.5, 0.5]),
    383    FP.abstract.toInterval([kValue.f64.positive.min, kValue.f64.positive.max]),
    384    FP.abstract.toInterval([kValue.f64.positive.subnormal.min, kValue.f64.positive.subnormal.max]),
    385    FP.abstract.toInterval([kValue.f64.negative.subnormal.min, kValue.f64.negative.subnormal.max]),
    386    FP.abstract.toInterval([kValue.f64.negative.infinity, kValue.f64.positive.infinity]),
    387  ]) {
    388    const s = new BinaryStream(new Uint8Array(1024).buffer);
    389    serializeFPInterval(s, interval);
    390    const d = new BinaryStream(s.buffer().buffer);
    391    const deserialized = deserializeFPInterval(d);
    392    t.expect(
    393      objectEquals(interval, deserialized),
    394      `interval ${interval} -> serialize -> deserialize -> ${deserialized}`
    395    );
    396  }
    397 });
    398 
    399 g.test('expression_expectation').fn(t => {
    400  for (const expectation of [
    401    // Value
    402    f32(123),
    403    vec2(f32(1), f32(2)),
    404    // Interval
    405    FP.f32.toInterval([-0.5, 0.5]),
    406    FP.f32.toInterval([kValue.f32.positive.min, kValue.f32.positive.max]),
    407    // Intervals
    408    [FP.f32.toInterval([-8.0, 0.5]), FP.f32.toInterval([2.0, 4.0])],
    409  ]) {
    410    const s = new BinaryStream(new Uint8Array(1024).buffer);
    411    serializeExpectation(s, expectation);
    412    const d = new BinaryStream(s.buffer().buffer);
    413    const deserialized = deserializeExpectation(d);
    414    t.expect(
    415      objectEquals(expectation, deserialized),
    416      `expectation ${expectation} -> serialize -> deserialize -> ${deserialized}`
    417    );
    418  }
    419 });
    420 
    421 /**
    422 * Temporarily enabled building of the data cache.
    423 * Required for Comparators to serialize.
    424 */
    425 function enableBuildingDataCache(f: () => void) {
    426  const wasBuildingDataCache = getIsBuildingDataCache();
    427  setIsBuildingDataCache(true);
    428  f();
    429  setIsBuildingDataCache(wasBuildingDataCache);
    430 }
    431 
    432 g.test('anyOf').fn(t => {
    433  enableBuildingDataCache(() => {
    434    for (const c of [
    435      {
    436        comparator: anyOf(i32(123)),
    437        testCases: [f32(0), f32(10), f32(122), f32(123), f32(124), f32(200)],
    438      },
    439    ]) {
    440      const s = new BinaryStream(new Uint8Array(1024).buffer);
    441      serializeComparator(s, c.comparator);
    442      const d = new BinaryStream(s.buffer().buffer);
    443      const deserialized = deserializeComparator(d);
    444      for (const val of c.testCases) {
    445        const got = deserialized.compare(val);
    446        const expect = c.comparator.compare(val);
    447        t.expect(
    448          got.matched === expect.matched,
    449          `comparator(${val}): got: ${expect.matched}, expect: ${got.matched}`
    450        );
    451      }
    452    }
    453  });
    454 });
    455 
    456 g.test('skipUndefined').fn(t => {
    457  enableBuildingDataCache(() => {
    458    for (const c of [
    459      {
    460        comparator: skipUndefined(i32(123)),
    461        testCases: [f32(0), f32(10), f32(122), f32(123), f32(124), f32(200)],
    462      },
    463      {
    464        comparator: skipUndefined(undefined),
    465        testCases: [f32(0), f32(10), f32(122), f32(123), f32(124), f32(200)],
    466      },
    467    ]) {
    468      const s = new BinaryStream(new Uint8Array(1024).buffer);
    469      serializeComparator(s, c.comparator);
    470      const d = new BinaryStream(s.buffer().buffer);
    471      const deserialized = deserializeComparator(d);
    472      for (const val of c.testCases) {
    473        const got = deserialized.compare(val);
    474        const expect = c.comparator.compare(val);
    475        t.expect(
    476          got.matched === expect.matched,
    477          `comparator(${val}): got: ${expect.matched}, expect: ${got.matched}`
    478        );
    479      }
    480    }
    481  });
    482 });