public void Service_end_to_end_no_deki()
        {
            // set up mocks for all the support service calls
            string apikey     = "abc";
            XUri   deki       = new XUri("http://mock/deki");
            int    dekiCalled = 0;

            MockPlug.Register(deki, delegate(Plug p, string v, XUri u, DreamMessage r, Result <DreamMessage> r2) {
                _log.DebugFormat("deki: {0}:{1}", v, u);
                dekiCalled++;
                r2.Return(DreamMessage.Ok());
            });

            XUri           varnish           = new XUri("http://mock/varnish");
            AutoResetEvent varnishResetEvent = new AutoResetEvent(false);
            string         varnishHeader     = "";
            int            varnishCalled     = 0;

            MockPlug.Register(varnish, delegate(Plug p, string v, XUri u, DreamMessage r, Result <DreamMessage> r2) {
                _log.DebugFormat("varnish: {0}:{1}", v, u);
                if (v == "PURGE")
                {
                    varnishHeader = r.Headers["X-Purge-Url"];
                    varnishCalled++;
                    varnishResetEvent.Set();
                }
                r2.Return(DreamMessage.Ok());
            });

            XUri           subscribe            = new XUri("http://mock/sub");
            XUri           subscriptionLocation = subscribe.At("testsub");
            AutoResetEvent subscribeResetEvent  = new AutoResetEvent(false);
            XUri           subscribeCalledUri   = null;
            XDoc           subscribePosted      = null;

            MockPlug.Register(subscribe, delegate(Plug p, string v, XUri u, DreamMessage r, Result <DreamMessage> r2) {
                subscribeCalledUri = u;
                if (u == subscribe.At("subscribers"))
                {
                    _log.Debug("creating subscription");
                    DreamMessage msg     = DreamMessage.Ok(new XDoc("x"));
                    msg.Headers.Location = subscriptionLocation;
                    subscribeResetEvent.Set();
                    r2.Return(msg);
                }
                else
                {
                    _log.Debug("updating subscription");
                    subscribePosted = r.ToDocument();
                    subscribeResetEvent.Set();
                    r2.Return(DreamMessage.Ok());
                }
            });

            // set up service
            _log.Debug("set up service");
            DreamServiceInfo serviceInfo = DreamTestHelper.CreateService(
                _hostInfo,
                typeof(VarnishPurgeService),
                "varnish",
                new XDoc("config")
                .Elem("uri.deki", deki)
                .Elem("uri.varnish", varnish)
                .Elem("uri.pubsub", subscribe)
                .Elem("varnish-purge-delay", 1)
                .Elem("apikey", apikey)
                );
            Plug service = serviceInfo.WithInternalKey().AtLocalHost;

            // expect:
            // - storage was queried
            // - subscription was created on subscribe
            Assert.IsTrue(subscribeResetEvent.WaitOne(100, true));
            Assert.AreEqual(subscribe.At("subscribers"), subscribeCalledUri);

            // post page varnish event
            service.At("queue").Post(
                new XDoc("deki-event")
                .Attr("wikiid", "abc")
                .Elem("channel", "event://abc/deki/pages/create")
                .Elem("pageid", "1")
                .Elem("path", "x/y/z"));
            Assert.IsTrue(varnishResetEvent.WaitOne(5000, false));
            Assert.AreEqual(0, dekiCalled);
            Assert.AreEqual(1, varnishCalled);
            Assert.AreEqual("^/((x/y/z|index\\.php\\?title=x/y/z)[\\?&]?|@api/deki/pages/1/?).*$", varnishHeader);
            Assert.IsTrue(Wait.For(() => varnishCalled == 1, 10.Seconds()), "varnish wasn't called");
        }
Example #2
0
        public void Providing_externalLuceneUri_posts_dekipubsub_plug_info_on_that_service()
        {
            var  mockLuceneUri  = new XUri("http://mock/lucene");
            var  mockLucene     = MockPlug.Register(mockLuceneUri);
            XDoc pubsubPlugInfo = null;

            mockLucene.Expect()
            .Verb("POST")
            .Uri(mockLuceneUri.At("subscriptions")).RequestDocument(x => { pubsubPlugInfo = x; return(true); })
            .Response(DreamMessage.Ok());
            var dekiConfig = new XDoc("config")
                             .Elem("apikey", "123")
                             .Elem("path", "deki")
                             .Elem("sid", "http://services.mindtouch.com/deki/draft/2006/11/dekiwiki")
                             .Elem("deki-path", Utils.Settings.DekiPath)
                             .Elem("deki-resources-path", Utils.Settings.DekiResourcesPath)
                             .Elem("imagemagick-convert-path", Utils.Settings.ImageMagickConvertPath)
                             .Elem("imagemagick-identify-path", Utils.Settings.ImageMagickIdentifyPath)
                             .Elem("princexml-path", Utils.Settings.PrinceXmlPath)
                             .Start("indexer").Attr("src", mockLuceneUri).End()
                             .Start("page-subscription")
                             .Elem("accumulation-time", "0")
                             .End()
                             .Start("wikis")
                             .Start("config")
                             .Attr("id", "default")
                             .Elem("host", "*")
                             .Start("page-subscription")
                             .Elem("from-address", "*****@*****.**")
                             .End()
                             .Elem("db-server", "na")
                             .Elem("db-port", "3306")
                             .Elem("db-catalog", "wikidb")
                             .Elem("db-user", "wikiuser")
                             .Start("db-password").Attr("hidden", "true").Value("password").End()
                             .Elem("db-options", "pooling=true; Connection Timeout=5; Protocol=socket; Min Pool Size=2; Max Pool Size=50; Connection Reset=false;character set=utf8;ProcedureCacheSize=25;Use Procedure Bodies=true;")
                             .End()
                             .End();
            var apikey   = dekiConfig["apikey"].AsText;
            var hostInfo = DreamTestHelper.CreateRandomPortHost(new XDoc("config").Elem("apikey", apikey));

            hostInfo.Host.Self.At("load").With("name", "mindtouch.deki").Post(DreamMessage.Ok());
            hostInfo.Host.Self.At("load").With("name", "mindtouch.deki.services").Post(DreamMessage.Ok());
            var deki = DreamTestHelper.CreateService(hostInfo, dekiConfig);

            Assert.IsTrue(mockLucene.WaitAndVerify(TimeSpan.FromSeconds(10)), mockLucene.VerificationFailure);
            var pubsubPlug = Plug.New(pubsubPlugInfo["@href"].AsUri);

            foreach (var header in pubsubPlugInfo["header"])
            {
                pubsubPlug.WithHeader(header["name"].AsText, header["value"].AsText);
            }
            var setCookies = DreamCookie.ParseAllSetCookieNodes(pubsubPlugInfo["set-cookie"]);

            if (setCookies.Count > 0)
            {
                pubsubPlug.CookieJar.Update(setCookies, null);
            }
            var subscriptionSet = new XDoc("subscription-set")
                                  .Elem("uri.owner", mockLuceneUri)
                                  .Start("subscription")
                                  .Elem("channel", "event://*/foo")
                                  .Start("recipient")
                                  .Attr("authtoken", apikey)
                                  .Elem("uri", mockLuceneUri)
                                  .End()
                                  .End();
            var subscription = pubsubPlug.At("subscribers").Post(subscriptionSet);

            Assert.AreEqual(DreamStatus.Created, subscription.Status);
        }
 public void PerTestSetup()
 {
     _hostInfo = DreamTestHelper.CreateRandomPortHost();
 }
Example #4
0
        public void Create_entries_in_cache()
        {
            DekiScriptLiteral result;

            // create web-cahce extension service
            var webcache = DreamTestHelper.CreateService(
                _hostInfo,
                new XDoc("config")
                .Elem("class", typeof(WebCacheService).FullName)
                .Elem("path", "webcache")
                );

            // extract entry points for web-cache functions
            var manifest = webcache.AtLocalHost.Get().AsDocument();
            var fetch    = Plug.New(manifest["function[name/text()='fetch']/uri"].AsUri);
            var store    = Plug.New(manifest["function[name/text()='store']/uri"].AsUri);
            var clear    = Plug.New(manifest["function[name/text()='clear']/uri"].AsUri);

            // create MAX_ITERATIONS entries in web-cache
            var sw = Stopwatch.StartNew();

            for (int i = 1; i <= MAX_ITERATIONS; ++i)
            {
                var key  = "key" + i;
                var list = new DekiScriptList()
                           .Add(DekiScriptExpression.Constant(key))
                           .Add(DekiScriptExpression.Constant(CONTENT));
                var response = store.Post(list.ToXml());
                var doc      = response.ToDocument();
                result = DekiScriptLiteral.FromXml(doc);
                _log.DebugFormat("webcache.store('{0}') -> {1}", key, result);
            }
            sw.Stop();
            _log.DebugFormat("webcache.store() all took {0:#,##0} seconds", sw.Elapsed.TotalSeconds);

            // shutdown web-cache service
            webcache.WithPrivateKey().AtLocalHost.Delete();

            // re-create web-cache extension service
            webcache = DreamTestHelper.CreateService(
                _hostInfo,
                new XDoc("config")
                .Elem("class", typeof(WebCacheService).FullName)
                .Elem("path", "webcache")
                );

            // re-extract entry points for web-cache functions
            manifest = webcache.AtLocalHost.Get().AsDocument();
            fetch    = Plug.New(manifest["function[name/text()='fetch']/uri"].AsUri);
            store    = Plug.New(manifest["function[name/text()='store']/uri"].AsUri);
            clear    = Plug.New(manifest["function[name/text()='clear']/uri"].AsUri);

            // loop over all entries in web-cache and fetch them
            sw = Stopwatch.StartNew();
            for (int i = 1; i <= MAX_ITERATIONS; ++i)
            {
                int count = 0;
                var key   = "key" + i;
                do
                {
                    result = DekiScriptLiteral.FromXml(fetch.Post(new DekiScriptList().Add(DekiScriptExpression.Constant(key)).ToXml()).ToDocument());
                    var text = ((DekiScriptList)result)[0].AsString();
                    if (text == CONTENT)
                    {
                        break;
                    }
                    Thread.Sleep(50);
                } while(++count < 100);
                if (count >= 100)
                {
                    Assert.Fail("too many attempts to load " + key);
                    return;
                }
            }
            sw.Stop();
            _log.DebugFormat("webcache.fetch() all took {0:#,##0} seconds", sw.Elapsed.TotalSeconds);

            // loop over all entries in web-cache and clear them out
            sw = Stopwatch.StartNew();
            for (int i = 1; i <= MAX_ITERATIONS; ++i)
            {
                var key  = "key" + i;
                var list = new DekiScriptList()
                           .Add(DekiScriptExpression.Constant(key));
                var response = clear.Post(list.ToXml());
                var doc      = response.ToDocument();
                result = DekiScriptLiteral.FromXml(doc);
                _log.DebugFormat("webcache.clear('{0}') -> {1}", key, result);
            }
            sw.Stop();
            _log.DebugFormat("webcache.clear() all took {0:#,##0} seconds", sw.Elapsed.TotalSeconds);

            // loop over all entries in web-cache and fetch them
            sw = Stopwatch.StartNew();
            for (int i = 1; i <= MAX_ITERATIONS; ++i)
            {
                var key = "key" + i;
                result = DekiScriptLiteral.FromXml(fetch.Post(new DekiScriptList().Add(DekiScriptExpression.Constant(key)).ToXml()).ToDocument());
                var text = ((DekiScriptList)result)[0].AsString();
                Assert.AreEqual(null, text, "entry " + key + " was not deleted");
            }
            sw.Stop();
            _log.DebugFormat("webcache.fetch() all took {0:#,##0} seconds", sw.Elapsed.TotalSeconds);

            // shutdown web-cache service again
            webcache.WithPrivateKey().AtLocalHost.Delete();
        }