public void testLoadGet() { storage = new LiteDBStorage(_testDbFilename); Assert.AreEqual(0, storage.TotalItems); var queue = new PersistentBlockingQueue(storage, new PayloadToJsonString()); var endpoint = new SnowplowHttpCollectorEndpoint(host: _collectorHostUri, port: 8080, protocol: HttpProtocol.HTTP, method: HttpMethod.GET, byteLimitGet: 50000); var emitter = new AsyncEmitter(endpoint: endpoint, queue: queue, sendLimit: 25); var clientSession = new ClientSession(_testClientSessionFilename); Assert.IsFalse(tracker.Started); tracker.Start(emitter: emitter, clientSession: clientSession, trackerNamespace: "testNamespace", appId: "testAppId", encodeBase64: false, synchronous: false); Assert.IsTrue(tracker.Started); for (int i = 0; i < 100; i++) { tracker.Track(new Structured() .SetCategory("exampleCategory") .SetAction("exampleAction") .SetLabel("exampleLabel") .SetProperty("exampleProperty") .SetValue(17) .Build() ); } tracker.Flush(); tracker.Stop(); Assert.IsFalse(tracker.Started); }
private AsyncEmitter buildMockEmitter() { var q = new PersistentBlockingQueue(new MockStorage(), new PayloadToJsonString()); AsyncEmitter e = new AsyncEmitter(new MockEndpoint(), q); return(e); }
public void testFailedItemsEnqueuedAgain() { var q = new PersistentBlockingQueue(new MockStorage(), new PayloadToJsonString()); AsyncEmitter e = new AsyncEmitter(new MockEndpoint() { Response = false }, q); // no events will send, and so they should be at the start of the queue e.Start(); var p = new Payload(); p.AddDict(new Dictionary <string, string>() { { "foo", "bar" } }); e.Input(p); Thread.Sleep(100); // this could be done better with triggers of some kind e.Stop(); var inQueue = q.Peek(1); Assert.AreEqual(1, inQueue.Count); }
public void testFlushStopsAfterFirstFailure() { var storage = new MockStorage(); var queue = new PersistentBlockingQueue(storage, new PayloadToJsonString()); var mockEndpoint = new MockEndpoint() { Response = false }; AsyncEmitter e = new AsyncEmitter(mockEndpoint, queue, sendLimit: 1); for (int i = 0; i < 100; i++) { var p = new Payload(); p.AddDict(new Dictionary <string, string>() { { "foo", "bar" } }); e.Input(p); } Assert.AreEqual(100, storage.TotalItems); Assert.IsFalse(e.Running); e.Flush(true); Assert.IsFalse(e.Running); Assert.AreEqual(1, mockEndpoint.CallCount); Assert.AreEqual(0, mockEndpoint.Result.SuccessIds.Count); Assert.AreEqual(1, mockEndpoint.Result.FailureIds.Count); Assert.AreEqual(100, storage.TotalItems); }
public void testMultipleConsumers() { var mockStorage = new MockStorage(); var q = new PersistentBlockingQueue(mockStorage, new PayloadToJsonString()); int expectedRecordCount = 1000; var producer = new MockProducer(expectedRecordCount, q); var producerThread = new Thread(new ThreadStart(producer.Produce)); producerThread.Start(); var threads = new List <Thread>(); var consumers = new List <MockConsumer>(); for (int i = 0; i < expectedRecordCount; i++) { var consumer = new MockConsumer(1, q); var consumerThread = new Thread(new ThreadStart(consumer.Consume)); consumerThread.Start(); threads.Add(consumerThread); consumers.Add(consumer); } threads.ForEach(t => { t.Join(100); }); var total = (from c in consumers select c.Consumed.Count).Sum(); bool allConsumedOneItem = !consumers.Any(item => { return(item.Consumed.Count != 1); }); Assert.IsTrue(allConsumedOneItem); Assert.AreEqual(expectedRecordCount, total); }
public void testAddRemoveThreaded() { var mockStorage = new MockStorage(); var q = new PersistentBlockingQueue(mockStorage, new PayloadToJsonString()); int expectedRecordCount = 1000; var consumer = new MockConsumer(expectedRecordCount, q); var producer = new MockProducer(expectedRecordCount / 2, q); var secondProducer = new MockProducer(expectedRecordCount / 2, q); var consumerThread = new Thread(new ThreadStart(consumer.Consume)); consumerThread.Start(); var producerThread = new Thread(new ThreadStart(producer.Produce)); producerThread.Start(); var secondProducerThread = new Thread(new ThreadStart(secondProducer.Produce)); secondProducerThread.Start(); consumerThread.Join(1000); // time out if errors Assert.AreEqual(expectedRecordCount, consumer.Consumed.Count); }
public void testConsumerTimeout() { var mockStorage = new MockStorage(); var q = new PersistentBlockingQueue(mockStorage, new PayloadToJsonString()); var consumer = new MockConsumer(1, q, 10); var consumerThread = new Thread(new ThreadStart(consumer.Consume)); consumerThread.Start(); consumerThread.Join(500); Assert.AreEqual(0, consumer.Consumed.Count); }
/// <summary> /// Start a tracker with a default emitter /// </summary> /// <param name="endpoint">Hostname of your collector</param> /// <param name="dbPath">A filename/path to store queued events in</param> /// <param name="method">The method used to send events to a collector. GET or POST</param> /// <param name="subject">Information on the user</param> /// <param name="clientSession"></param> /// <param name="trackerNamespace">Namespace of tracker</param> /// <param name="appId">Application ID of tracker</param> /// <param name="encodeBase64">Base64 encode collector parameters</param> /// <param name="synchronous">Whether to do I/O synchronously</param> /// <param name="desktopContextDelegate">Delegate for fetching the desktop context</param> /// <param name="mobileContextDelegate">Delegate for fetching the mobile context</param> /// <param name="geoLocationContextDelegate">Delegate for fetching the geo-location context</param> /// <param name="l">A logger to emit an activity stream to</param> public void Start(string endpoint, string dbPath, HttpMethod method = HttpMethod.POST, Subject subject = null, ClientSession clientSession = null, string trackerNamespace = null, string appId = null, bool encodeBase64 = true, bool synchronous = true, DesktopContextDelegate desktopContextDelegate = null, MobileContextDelegate mobileContextDelegate = null, GeoLocationContextDelegate geoLocationContextDelegate = null, ILogger l = null) { AsyncEmitter emitter; lock (_lock) { var dest = new SnowplowHttpCollectorEndpoint(endpoint, method: method, l: l); var storage = new LiteDBStorage(dbPath); _storage = storage; var queue = new PersistentBlockingQueue(storage, new PayloadToJsonString()); emitter = new AsyncEmitter(dest, queue, l: l); } Start(emitter, subject, clientSession, trackerNamespace, appId, synchronous, encodeBase64, desktopContextDelegate, mobileContextDelegate, geoLocationContextDelegate, l); }
public void testTracker() { var storage = new LiteDBStorage(_testDbFilename); Assert.AreEqual(0, storage.TotalItems); var queue = new PersistentBlockingQueue(storage, new PayloadToJsonString()); var getRequestMock = new MockGet(); var postRequestMock = new MockPost(); var endpoint = new SnowplowHttpCollectorEndpoint("snowplowanalytics.com", postMethod: new SnowplowHttpCollectorEndpoint.PostDelegate(postRequestMock.HttpPost), getMethod: new SnowplowHttpCollectorEndpoint.GetDelegate(getRequestMock.HttpGet)); Assert.IsFalse(tracker.Started); tracker.Start(new AsyncEmitter(endpoint, queue, sendLimit: 1), trackerNamespace: "testNamespace", appId: "testAppId", encodeBase64: false); Assert.IsTrue(tracker.Started); Assert.IsTrue(ensureSubjectSet(tracker)); Assert.IsTrue(ensurePageViewsWorkGet(tracker, getRequestMock)); Assert.IsTrue(ensureStructEventsWorkGet(tracker, getRequestMock)); Assert.IsTrue(ensureEcommerceTransactionWorksGet(tracker, getRequestMock)); Assert.IsTrue(ensureUnstructEventGet(tracker, getRequestMock)); tracker.Stop(); Assert.IsFalse(tracker.Started); // Restart with base64 on tracker.Start(new AsyncEmitter(endpoint, queue, sendLimit: 1), trackerNamespace: "testNamespace", appId: "testAppId", encodeBase64: true); Assert.IsTrue(tracker.Started); Assert.IsTrue(ensureUnstructEventGet(tracker, getRequestMock, true)); Assert.IsTrue(ensureScreenViewWorksGet(tracker, getRequestMock, true)); Assert.IsTrue(ensureTimingWorksGet(tracker, getRequestMock, true)); Assert.IsTrue(ensureContextsWorkGet(tracker, getRequestMock, true)); Assert.IsTrue(ensureSettersWorkGet(tracker, getRequestMock)); tracker.Stop(); Assert.IsFalse(tracker.Started); }
public void testAddRemoveOne() { var storage = new MockStorage(); var queue = new PersistentBlockingQueue(storage, new PayloadToJsonString()); var dict = new Dictionary <string, string>(); dict.Add("hello", "world"); var samplePayload = new Payload(); samplePayload.AddDict(dict); var payload = new List <Payload>(); payload.Add(samplePayload); queue.Enqueue(payload); var actualPayload = queue.Peek(1); Assert.AreEqual(1, actualPayload.Count); CollectionAssert.AreEqual(samplePayload.Payload, actualPayload[0].Item2.Payload); }
public void testBackoffInterval() { // because of the back off period (5sec +), this event should only be sent once var q = new PersistentBlockingQueue(new MockStorage(), new PayloadToJsonString()); var mockEndpoint = new MockEndpoint() { Response = false }; AsyncEmitter e = new AsyncEmitter(mockEndpoint, q); e.Start(); var p = new Payload(); p.AddDict(new Dictionary <string, string>() { { "foo", "bar" } }); e.Input(p); Thread.Sleep(100); e.Stop(); Assert.AreEqual(1, mockEndpoint.CallCount); }
/// <summary> /// Inits the Snowplow Tracker; after this point it can be accessed globally. /// </summary> /// <param name="emitterUri">The emitter URI</param> /// <param name="protocol">The protocol to use</param> /// <param name="port">The port the collector is on</param> /// <param name="method">The method to use</param> /// <param name="useClientSession">Whether to enable client session</param> /// <param name="useMobileContext">Whether to enable mobile contexts</param> /// <param name="useGeoLocationContext">Whether to enable geo-location contexts</param> public static void Init( string emitterUri, HttpProtocol protocol = HttpProtocol.HTTP, int?port = null, HttpMethod method = HttpMethod.GET, bool useClientSession = false, bool useMobileContext = false, bool useGeoLocationContext = false) { var logger = new ConsoleLogger(); var dest = new SnowplowHttpCollectorEndpoint(emitterUri, method: method, port: port, protocol: protocol, l: logger); // Note: Maintain reference to Storage as this will need to be disposed of manually _storage = new LiteDBStorage(SnowplowTrackerPlatformExtension.Current.GetLocalFilePath("events.db")); var queue = new PersistentBlockingQueue(_storage, new PayloadToJsonString()); // Note: When using GET requests the sendLimit equals the number of concurrent requests - to many of these will break your application! var sendLimit = method == HttpMethod.GET ? 10 : 100; // Note: To make the tracker more battery friendly and less likely to drain batteries there are two settings to take note of here: // 1. The stopPollIntervalMs: Controls how often we look to the database for more events // 2. The deviceOnlineMethod: Is run before going to the database or attempting to send events, this will prevent any I/O from // occurring unless you have an active network connection var emitter = new AsyncEmitter(dest, queue, sendLimit: sendLimit, stopPollIntervalMs: 1000, sendSuccessMethod: EventSuccessCallback, deviceOnlineMethod: SnowplowTrackerPlatformExtension.Current.IsDeviceOnline, l: logger); var userId = PropertyManager.GetStringValue(KEY_USER_ID, SnowplowCore.Utils.GetGUID()); PropertyManager.SaveKeyValue(KEY_USER_ID, userId); var subject = new Subject() .SetPlatform(Platform.Mob) .SetUserId(userId) .SetLang("en"); if (useClientSession) { _clientSession = new ClientSession(SnowplowTrackerPlatformExtension.Current.GetLocalFilePath("client_session.dict"), l: logger); } // Note: You can either attach contexts to each event individually or for the more common contexts such as Desktop, Mobile and GeoLocation // you can pass a delegate method which will then be called for each event automatically. MobileContextDelegate mobileContextDelegate = null; if (useMobileContext) { mobileContextDelegate = SnowplowTrackerPlatformExtension.Current.GetMobileContext; } GeoLocationContextDelegate geoLocationContextDelegate = null; if (useMobileContext) { geoLocationContextDelegate = SnowplowTrackerPlatformExtension.Current.GetGeoLocationContext; } // Attach the created objects and begin all required background threads! Instance.Start(emitter: emitter, subject: subject, clientSession: _clientSession, trackerNamespace: _trackerNamespace, appId: _appId, encodeBase64: false, synchronous: false, mobileContextDelegate: mobileContextDelegate, geoLocationContextDelegate: geoLocationContextDelegate, l: logger); // Reset session counters SessionMadeCount = 0; SessionSuccessCount = 0; SessionFailureCount = 0; }