Skip to content

Commit

Permalink
add notification mgr (#2281)
Browse files Browse the repository at this point in the history
  • Loading branch information
Karlie-777 committed Feb 27, 2024
1 parent caf4dd9 commit 9d2267e
Show file tree
Hide file tree
Showing 21 changed files with 927 additions and 113 deletions.
1 change: 1 addition & 0 deletions .aiAutoMinify.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
"_eSetDynamicPropertyFlags",
"CallbackType",
"eEventsDiscardedReason",
"eBatchDiscardedReason",
"FeatureOptInMode",
"CdnFeatureMode",
"eLoggingSeverity",
Expand Down
2 changes: 1 addition & 1 deletion channels/offline-channel-js/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ The Offline Channel supports the saving of events when your application is offli

| Name | Type | Default | Description |
|------|------|---------|-------------|
| maxStorageSizeInBytes | [Optional]| 5000000 | The max size in bytes that should be used for storing events. |
| maxStorageSizeInBytes | [Optional]| 5000000 | The max size in bytes that should be used for storing events in local/session storage. |
| storageKeyPrefix | [Optional] | AIOffline | The storage key prefix that should be used when storing events in persistent storage. |
| minPersistenceLevel | [Optional] | `EventPersistence.Normal` or 1 | Identifies the minimum level that will be cached in the offline channel. Valid values of this setting are defined by the `EventPersistence` enum, currently Normal (1) and Critical (2) with the default value being Normal (1), which means all events without a persistence level set or with invalid persistence level will be marked as Normal(1) events.|
| providers | [Optional] | [`eStorageProviders.LocalStorage, eStorageProviders.IndexedDB`]| Identifies the StorageProviders that should be used by the system if available, the first available provider will be used. Valid available values are defined by the `eStorageProviders` enum. </br> Note: LocalStorage will be used to save unload events even if it is not in the providers list. |
Expand Down
4 changes: 2 additions & 2 deletions channels/offline-channel-js/Tests/Unit/src/TestHelper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,13 +78,13 @@ export class TestChannel extends BaseTelemetryPlugin implements IChannelControls
}
}

export function mockTelemetryItem(): ITelemetryItem {
export function mockTelemetryItem(level?: number): ITelemetryItem {
let evt = {
ver: "testVer" + Math.random(),
name:"testName",
time: "testTime",
iKey:"testKey",
baseData: {pro1: "prop1"},
baseData: {pro1: "prop1", persistence: level},
baseType: "testType"
} as ITelemetryItem;
return evt;
Expand Down
363 changes: 358 additions & 5 deletions channels/offline-channel-js/Tests/Unit/src/channel.tests.ts

Large diffs are not rendered by default.

29 changes: 24 additions & 5 deletions channels/offline-channel-js/Tests/Unit/src/dbprovider.tests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export class OfflineDbProviderTests extends AITestClass {
private coreConfig: IConfig & IConfiguration;
private ctx: any;
private preEvts: IStorageTelemetryItem[] = [];
private batchDrop: any;

public testInitialize() {
super.testInitialize();
Expand All @@ -23,6 +24,7 @@ export class OfflineDbProviderTests extends AITestClass {
this.core = new AppInsightsCore();
this.core.initialize(this.coreConfig, [channel]);
this.ctx = {};
this.batchDrop = [];
}

public testCleanup() {
Expand All @@ -32,6 +34,7 @@ export class OfflineDbProviderTests extends AITestClass {
});
this.core = null as any;
this.coreConfig = null as any;
this.batchDrop = [];
}

public registerTests() {
Expand All @@ -45,15 +48,14 @@ export class OfflineDbProviderTests extends AITestClass {
let providerCxt = {
itemCtx: itemCtx,
storageConfig: storageConfig,
endpoint:DEFAULT_BREEZE_ENDPOINT + DEFAULT_BREEZE_PATH
endpoint: DEFAULT_BREEZE_ENDPOINT + DEFAULT_BREEZE_PATH
}
let isInit = provider.initialize(providerCxt);
Assert.ok(isInit, "init process is successful");
let ctx = provider["_getDbgPlgTargets"]();
let expectedStorageKey = "AIOffline_1_dc.services.visualstudio.com";
Assert.equal(ctx[0], expectedStorageKey, "should have expected storage");
let expectedMaxStorage = 5000000;
Assert.equal(ctx[1], expectedMaxStorage, "default MaxStorage is set");
Assert.equal(ctx[1], "dc.services.visualstudio.com", "default endpoint is set");
let expectedMaxStorageTime = 10080000;
Assert.equal(ctx[2], expectedMaxStorageTime, "default Max time is set");
Assert.ok(!provider.supportsSyncRequests(), "support sync should be set to false");
Expand Down Expand Up @@ -440,14 +442,20 @@ export class OfflineDbProviderTests extends AITestClass {
name: "IndexedDbProvider: removeEvents should delete expected events",
stepDelay: 100,
steps: [() => {
this.core.addNotificationListener({
offlineBatchDrop: (cnt, reason)=> {
this.batchDrop.push({cnt: cnt, reason: reason});
}
});
let endpoint = DEFAULT_BREEZE_ENDPOINT + DEFAULT_BREEZE_PATH;
let provider = new IndexedDbProvider();
let itemCtx = this.core.getProcessTelContext();
let storageConfig = createDynamicConfig({autoClean: true, inStorageMaxTime:1}).cfg; // this should clean all previous events
let providerCxt = {
itemCtx: itemCtx,
storageConfig: storageConfig,
endpoint: endpoint
endpoint: endpoint,
notificationMgr: this.core.getNotifyMgr()
};
let evt = TestHelper.mockEvent(endpoint, 3, false);
doAwait(provider.initialize(providerCxt), (val) => {
Expand Down Expand Up @@ -575,6 +583,8 @@ export class OfflineDbProviderTests extends AITestClass {
}, "Wait for get Events1 response" + new Date().toISOString(), 15, 1000) as any).concat(PollingAssert.createPollingAssert(() => {
let isclosed = this.ctx.isclosed;
if (isclosed) {
Assert.equal(this.batchDrop.length, 1, "notification should be called once"); // sent in clean process during initialization
Assert.equal(this.batchDrop[0].reason, 3, "notification should be called with expected reason time exceeded");
return true;
}
return false;
Expand Down Expand Up @@ -688,14 +698,20 @@ export class OfflineDbProviderTests extends AITestClass {
stepDelay: 100,
useFakeTimers: true,
steps: [() => {
this.core.addNotificationListener({
offlineBatchDrop: (cnt, reason)=> {
this.batchDrop.push({cnt: cnt, reason: reason});
}
});
let endpoint = DEFAULT_BREEZE_ENDPOINT + DEFAULT_BREEZE_PATH;
let provider = new IndexedDbProvider();
let itemCtx = this.core.getProcessTelContext();
let storageConfig = createDynamicConfig({inStorageMaxTime: 10000}).cfg;
let providerCxt = {
itemCtx: itemCtx,
storageConfig: storageConfig,
endpoint: endpoint
endpoint: endpoint,
notificationMgr: this.core.getNotifyMgr()
};

doAwait(provider.initialize(providerCxt), (val) => {
Expand Down Expand Up @@ -799,6 +815,9 @@ export class OfflineDbProviderTests extends AITestClass {
}, "Wait for get Events1 response" + new Date().toISOString(), 15, 1000) as any).concat(PollingAssert.createPollingAssert(() => {
let isclosed = this.ctx.isclosed;
if (isclosed) {
Assert.equal(this.batchDrop.length, 1, "notification should be called once");
Assert.equal(this.batchDrop[0].cnt, 2, "notification should be called with 2 count");
Assert.equal(this.batchDrop[0].reason, 3, "notification should be called with expected reason clean time exceeded");
return true;
}
return false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ import { AITestClass, Assert } from "@microsoft/ai-test-framework";
import {IPostTransmissionTelemetryItem} from "../../../src/Interfaces/IInMemoryBatch";
import { InMemoryBatch } from "../../../src/InMemoryBatch";
import { DiagnosticLogger, IDiagnosticLogger, arrForEach } from "@microsoft/applicationinsights-core-js";
import { base64Decode, base64Encode, getEndpointDomain } from "../../../src/Helpers/Utils";
import { base64Decode, base64Encode, forEachMap, getEndpointDomain, getPersistence } from "../../../src/Helpers/Utils";
import { IStorageTelemetryItem } from "../../../src/Interfaces/IOfflineProvider";


export class OfflineInMemoryBatchTests extends AITestClass {
private _logger: IDiagnosticLogger;
Expand Down Expand Up @@ -111,6 +113,61 @@ export class OfflineInMemoryBatchTests extends AITestClass {
}

});

this.testCase({
name: "Get Persistent Level: Get persistent level from a telemetry item",
test: () => {
let arr1 = [
null,
{},
{name: "test"},
{name: "test", baseData: {prop1: "prop1"}, data: {prop1: "prop1"}},
{name: "test", persistence: 1},
{name: "test", baseData: {persistence: 1, prop1: "prop1"}},
{name: "test", data: {persistence: 1, prop1: "prop1"}},
{name: "test", baseData: {persistence: 1, prop1: "prop1"}, data: {persistence: 2, prop1: "prop1"}},
{name: "test", persistence: 1, baseData: {persistence: 2, prop1: "prop1"}, data: {persistence: 2, prop1: "prop1"}}
];

arrForEach(arr1, (item) => {
let level = getPersistence(item as any);
Assert.equal(level, 1, "should get expected level");
});

}

});

this.testCase({
name: "Util for order map: should get events id in order",
test: () => {
let arr1 = ["1", "5.1", "2.abc", "6.jdfhhdf", "4.123","8.123"];
let expectedArr = ["2.abc", "4.123", "5.1", "6.jdfhhdf", "8.123", "1"];
let evts: {[key: string]:IStorageTelemetryItem} = {};
let idArr: string[] = [];

arrForEach(arr1, (id) => {
let evt = mockStorageItem(id);
evts[id] = evt;
});

forEachMap({}, (val, key) => {
idArr.push(key);
return true;
}, true);


forEachMap(evts, (val, key) => {
idArr.push(key);
return true;
}, true);

Assert.deepEqual(idArr, expectedArr, "should get expected ordered id array");


}

});
}
}

Expand All @@ -125,4 +182,14 @@ function mockPostTransmissionTelemetryItem(): IPostTransmissionTelemetryItem {

} as IPostTransmissionTelemetryItem;
return evt;
}

function mockStorageItem(id: string): IStorageTelemetryItem {
let evt = {
id: id,
urlString: "testString",
data: "testData"
} as IStorageTelemetryItem;
return evt;

}
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ import { ChannelTests } from "./channel.tests";
import { Offlinetimer } from "./offlinetimer.tests";

export function runTests() {
new OfflineIndexedDBTests().registerTests();
new OfflineWebProviderTests().registerTests();
new OfflineDbProviderTests().registerTests();
new OfflineInMemoryBatchTests().registerTests();
new OfflineBatchHandlerTests().registerTests();
// new OfflineIndexedDBTests().registerTests();
// new OfflineWebProviderTests().registerTests();
// new OfflineDbProviderTests().registerTests();
// new OfflineInMemoryBatchTests().registerTests();
// new OfflineBatchHandlerTests().registerTests();
new ChannelTests().registerTests();
new Offlinetimer().registerTests();
// new Offlinetimer().registerTests();
}
Loading

0 comments on commit 9d2267e

Please sign in to comment.