Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Storage: fix clear and removeItem #1136

Merged
merged 7 commits into from
Feb 28, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
8 changes: 4 additions & 4 deletions src/main-thread/commands/storage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,8 @@ export const StorageProcessor: CommandExecutorInterface = (strings, nodeContext,

// TODO(choumx): Clean up key/value strings (or don't store them in the first place)
// to avoid leaking memory.
const key = keyIndex >= 0 ? strings.get(keyIndex) : '';
const value = valueIndex >= 0 ? strings.get(valueIndex) : null;
const key = keyIndex > 0 ? strings.get(keyIndex - 1) : '';
const value = valueIndex > 0 ? strings.get(valueIndex - 1) : null;

if (operation === GetOrSet.GET) {
get(location, key);
Expand All @@ -82,8 +82,8 @@ export const StorageProcessor: CommandExecutorInterface = (strings, nodeContext,
const keyIndex = mutations[startPosition + StorageMutationIndex.Key];
const valueIndex = mutations[startPosition + StorageMutationIndex.Value];

const key = keyIndex >= 0 ? strings.get(keyIndex) : null;
const value = valueIndex >= 0 ? strings.get(valueIndex) : null;
const key = keyIndex > 0 ? strings.get(keyIndex - 1) : null;
const value = valueIndex > 0 ? strings.get(valueIndex - 1) : null;

return {
type: 'STORAGE',
Expand Down
5 changes: 3 additions & 2 deletions src/main-thread/strings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,11 @@ export class StringContext {
/**
* Stores a string in mapping and returns the index of the location.
* @param value string to store
* @return location in map
* @return {number}
*/
store(value: string): void {
store(value: string): number {
this.strings.push(value);
return this.strings.length - 1;
}

/**
Expand Down
25 changes: 24 additions & 1 deletion src/test/main-thread/commands/storage.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,17 @@ import { TransferrableKeys } from '../../../transfer/TransferrableKeys';

const test = anyTest as TestInterface<{}>;

type SetStorageMeta = { location: StorageLocation; key: string | null; value: string | null };

function getStorageProcessor(strings: string[]): {
processor: CommandExecutor;
messages: Array<MessageToWorker>;
getLastSetStorage: () => any;
} {
const stringCtx = new StringContext();
stringCtx.storeValues(strings);
const messages: Array<MessageToWorker> = [];
let lastSetStorage: null | SetStorageMeta = null;

const processor = StorageProcessor(
stringCtx,
Expand All @@ -34,12 +38,16 @@ function getStorageProcessor(strings: string[]): {
getStorage() {
return Promise.resolve({ hello: 'world' });
},
setStorage(location: StorageLocation, key: string | null, value: string | null) {
lastSetStorage = { location, key, value };
},
} as unknown as Sanitizer,
} as WorkerDOMConfiguration,
);
return {
processor,
messages,
getLastSetStorage: () => lastSetStorage,
};
}

Expand All @@ -48,7 +56,7 @@ test('StorageProcessor sends storage value event to worker', async (t) => {
const mutation: number[] = [];
mutation[StorageMutationIndex.Operation] = GetOrSet.GET;
mutation[StorageMutationIndex.Location] = StorageLocation.AmpState;
mutation[StorageMutationIndex.Key] = 0;
mutation[StorageMutationIndex.Key] = 1;
const mutations = new Uint16Array(mutation);

processor.execute(mutations, 0, true);
Expand All @@ -63,3 +71,18 @@ test('StorageProcessor sends storage value event to worker', async (t) => {
t.is(messages.length, 1);
t.deepEqual(messages, [expectedMessage]);
});

test('StorageProcessor handles deletion event from worker', async (t) => {
const { processor, getLastSetStorage } = getStorageProcessor(['t', 'hello']);
const mutation: number[] = [];
mutation[StorageMutationIndex.Operation] = GetOrSet.SET;
mutation[StorageMutationIndex.Location] = StorageLocation.Local;
mutation[StorageMutationIndex.Key] = 2;
mutation[StorageMutationIndex.Value] = 0;
const mutations = new Uint16Array(mutation);

processor.execute(mutations, 0, true);
await Promise.resolve(setTimeout);

t.deepEqual(getLastSetStorage(), { location: StorageLocation.Local, key: 'hello', value: null });
});
11 changes: 2 additions & 9 deletions src/test/main-thread/deserializeTransferrableObject.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ test('Deserializes float arguments', (t) => {
test('Deserializes string arguments', (t) => {
const { stringContext, nodeContext } = t.context;

const serializedArgs = [TransferrableObjectType.String, storeString(stringContext, 'textArg')];
const serializedArgs = [TransferrableObjectType.String, stringContext.store('textArg')];
const buffer = new Uint16Array(serializedArgs);
const { args: deserializedArgs } = deserializeTransferrableObject(buffer, 0, 1, stringContext, nodeContext);

Expand Down Expand Up @@ -104,7 +104,7 @@ test('Deserializes varying types', (t) => {

// argument 2: String
const stringArg = 'textArg';
const stringId = storeString(stringContext, stringArg);
const stringId = stringContext.store(stringArg);

// argument 3: Object
const objectId = 7;
Expand Down Expand Up @@ -155,13 +155,6 @@ test('Returns the correct end offset', (t) => {
t.is(buffer[endOffset], 32);
});

// main-thread's strings API does not return an ID when storing a string
// so for convenience:
function storeString(stringContext: StringContext, text: string, currentIndex = -1) {
stringContext.store(text);
return ++currentIndex;
}

/**
* Used to compare float value similarity in tests.
* @param expected
Expand Down
11 changes: 3 additions & 8 deletions src/test/main-thread/object-creation.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ test('Object creation with mutation at a zero offset', (t) => {
objectCreationProcessor.execute(
new Uint16Array([
TransferrableMutationType.OBJECT_CREATION,
storeString(stringContext, methodName),
stringContext.store(methodName),
objectId,
4, // arg count
...serializedTarget,
Expand Down Expand Up @@ -141,7 +141,7 @@ test('Object creation with mutation at non-zero offset', (t) => {

const mutation = [
TransferrableMutationType.OBJECT_CREATION,
storeString(stringContext, methodName),
stringContext.store(methodName),
objectId,
4, // arg count
...serializedTarget,
Expand Down Expand Up @@ -180,7 +180,7 @@ test('Returns correct end offset', (t) => {

const mutation = [
TransferrableMutationType.OBJECT_CREATION,
storeString(stringContext, methodName),
stringContext.store(methodName),
1, // object ID (not important for this test)
4, // arg count
TransferrableObjectType.CanvasRenderingContext2D,
Expand All @@ -196,8 +196,3 @@ test('Returns correct end offset', (t) => {

t.is(mutationsArray[endOffset], 32);
});

function storeString(stringContext: StringContext, text: string, currentIndex = -1) {
stringContext.store(text);
return ++currentIndex;
}
20 changes: 3 additions & 17 deletions src/test/main-thread/object-mutation.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,7 @@ test('Mutation starts at a non-zero offset', (t) => {

const mutation = [
TransferrableMutationType.OBJECT_MUTATION,
storeString(stringContext, methodName),
stringContext.store(methodName),
4, // arg count
TransferrableObjectType.CanvasRenderingContext2D,
canvasElement._index_,
Expand Down Expand Up @@ -280,7 +280,7 @@ test('Returns correct end offset', (t) => {

const mutation = [
TransferrableMutationType.OBJECT_MUTATION,
storeString(stringContext, methodName),
stringContext.store(methodName),
4, // arg count
TransferrableObjectType.CanvasRenderingContext2D,
canvasElement._index_,
Expand All @@ -304,24 +304,10 @@ function executeCall(
stringContext: StringContext,
argCount: number,
serializedArgs: number[],
stringsIndex?: number,
) {
return mutationProcessor.execute(
new Uint16Array([
TransferrableMutationType.OBJECT_MUTATION,
storeString(stringContext, fnName, stringsIndex),
argCount,
...serializedTargetObject,
...serializedArgs,
]),
new Uint16Array([TransferrableMutationType.OBJECT_MUTATION, stringContext.store(fnName), argCount, ...serializedTargetObject, ...serializedArgs]),
0,
/* allow */ true,
);
}

// main-thread's strings API does not return an ID when storing a string
// so for convenience:
function storeString(stringContext: StringContext, text: string, currentIndex = -1) {
stringContext.store(text);
return ++currentIndex;
}
15 changes: 5 additions & 10 deletions src/test/main-thread/string-properties.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,8 @@ test.beforeEach((t) => {
test('setting property to a new string', (t) => {
const { stringContext, propertyProcessor, inputElement } = t.context;
const newValue = 'new value';
const storedValueKey = storeString(stringContext, 'value');
const storedNewValue = storeString(stringContext, newValue, storedValueKey);
const storedValueKey = stringContext.store('value');
const storedNewValue = stringContext.store(newValue);

propertyProcessor.execute(
new Uint16Array([TransferrableMutationType.PROPERTIES, inputElement._index_, storedValueKey, NumericBoolean.FALSE, storedNewValue]),
Expand All @@ -82,9 +82,9 @@ test('setting property back to an empty string', (t) => {
const { stringContext, propertyProcessor, inputElement } = t.context;
const firstUpdateValue = 'new value';
const secondUpdateValue = '';
const storedValueKey = storeString(stringContext, 'value');
const storedFirstUpdateValue = storeString(stringContext, firstUpdateValue, storedValueKey);
const storedSecondUpdateValue = storeString(stringContext, secondUpdateValue, storedFirstUpdateValue);
const storedValueKey = stringContext.store('value');
const storedFirstUpdateValue = stringContext.store(firstUpdateValue);
const storedSecondUpdateValue = stringContext.store(secondUpdateValue);

propertyProcessor.execute(
new Uint16Array([TransferrableMutationType.PROPERTIES, inputElement._index_, storedValueKey, NumericBoolean.FALSE, storedFirstUpdateValue]),
Expand All @@ -100,8 +100,3 @@ test('setting property back to an empty string', (t) => {
);
t.is(inputElement.value, secondUpdateValue);
});

function storeString(stringContext: StringContext, text: string, currentIndex = -1) {
stringContext.store(text);
return ++currentIndex;
}
10 changes: 8 additions & 2 deletions src/test/mutation-transfer/storage.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,13 @@ test.serial.cb('Storage.setItem', (t) => {
const { document, storage } = t.context;

expectMutations(document, (mutations) => {
t.deepEqual(mutations, [TransferrableMutationType.STORAGE, GetOrSet.SET, StorageLocation.Local, getForTesting('foo'), getForTesting('bar')]);
t.deepEqual(mutations, [
TransferrableMutationType.STORAGE,
GetOrSet.SET,
StorageLocation.Local,
getForTesting('foo')! + 1,
getForTesting('bar')! + 1,
]);
t.end();
});

Expand All @@ -54,7 +60,7 @@ test.serial.cb('Storage.removeItem', (t) => {
const { document, storage } = t.context;

expectMutations(document, (mutations) => {
t.deepEqual(mutations, [TransferrableMutationType.STORAGE, GetOrSet.SET, StorageLocation.Local, getForTesting('foo'), 0]);
t.deepEqual(mutations, [TransferrableMutationType.STORAGE, GetOrSet.SET, StorageLocation.Local, getForTesting('foo')! + 1, 0]);
t.end();
});

Expand Down
4 changes: 2 additions & 2 deletions src/worker-thread/Storage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ export function createStorage(document: Document | DocumentStub, location: Stora
const stringValue = String(value);
this[key] = stringValue;

transfer(document, [TransferrableMutationType.STORAGE, GetOrSet.SET, location, store(key), store(stringValue)]);
transfer(document, [TransferrableMutationType.STORAGE, GetOrSet.SET, location, store(key) + 1, store(stringValue) + 1]);
},
});
define(storage, 'removeItem', {
Expand All @@ -62,7 +62,7 @@ export function createStorage(document: Document | DocumentStub, location: Stora
TransferrableMutationType.STORAGE,
GetOrSet.SET,
location,
store(key),
store(key) + 1,
samouri marked this conversation as resolved.
Show resolved Hide resolved
0, // value == 0 represents deletion.
]);
},
Expand Down