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"); }
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(); }
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(); }