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);
        }
Пример #2
0
        private AsyncEmitter buildMockEmitter()
        {
            var          q = new PersistentBlockingQueue(new MockStorage(), new PayloadToJsonString());
            AsyncEmitter e = new AsyncEmitter(new MockEndpoint(), q);

            return(e);
        }
Пример #3
0
        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);
        }
Пример #4
0
        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);
        }
Пример #8
0
        /// <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);
        }
Пример #11
0
        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;
        }