public void Queue_survives_service_restart() { var queue = StringUtil.CreateAlphaNumericKey(4); var doc = new XDoc("foo").Elem("bar", "baz"); // queue item var response = _plug.At("queue", queue).Post(doc, new Result <DreamMessage>()).Wait(); response.AssertSuccess(); // destroy and recreate service _queueService.WithPrivateKey().AtLocalHost.Delete(new Result <DreamMessage>()).Wait().AssertSuccess(); var q = DreamTestHelper.CreateService(_hostInfo, "sid://mindtouch.com/2009/12/dream/queue", "queue", new XDoc("config").Elem("folder", Path.GetTempPath())); var p = q.WithInternalKey().AtLocalHost; // check size response = p.At("queue", queue, "size").Get(new Result <DreamMessage>()).Wait(); response.AssertSuccess(); Assert.AreEqual("1", response.ToDocument()["size"].AsText); // get item response = p.At("queue", queue).Get(new Result <DreamMessage>()).Wait(); response.AssertSuccess(); Assert.AreEqual(doc, response.ToDocument()); }
private void CreateStorageService() { var config = new XDoc("config") .Elem("folder", "test") .Elem("bucket", "test-bucket") .Elem("privatekey", "test-private") .Elem("publickey", "test-public"); _storage = DreamTestHelper.CreateService(_hostInfo, "sid://mindtouch.com/2010/10/dream/s3.storage", "store", config); }
private void CreateStorageService() { var config = new XDoc("config") .Elem("baseuri", _config.S3BaseUri) .Elem("folder", _config.RootPath) .Elem("bucket", _config.Bucket) .Elem("privatekey", _config.PrivateKey) .Elem("publickey", _config.PublicKey); _storage = DreamTestHelper.CreateService(_hostInfo, "sid://mindtouch.com/2010/10/dream/s3.storage", "store", config); }
public void Creating_two_QueueServices_with_same_path_throws_on_same_queue_access() { var path = Path.Combine(Path.Combine(Path.GetTempPath(), StringUtil.CreateAlphaNumericKey(6)), "duplicate"); var s1 = DreamTestHelper.CreateService(_hostInfo, "sid://mindtouch.com/2009/12/dream/queue", "q", new XDoc("config").Elem("folder", path)); var p1 = s1.WithInternalKey().AtLocalHost; var s2 = DreamTestHelper.CreateService(_hostInfo, "sid://mindtouch.com/2009/12/dream/queue", "q", new XDoc("config").Elem("folder", path)); var p2 = s2.WithInternalKey().AtLocalHost; var response = p1.At("queue", "duplo", "size").Get(new Result <DreamMessage>()).Wait(); response.AssertSuccess(); response = p2.At("queue", "duplo", "size").Get(new Result <DreamMessage>()).Wait(); response.AssertStatus(DreamStatus.InternalError); s1.WithPrivateKey().AtLocalHost.Delete(); Directory.Delete(path, true); }
public void FixtureSetup() { _indexRebuilderMock = new IndexRebuilderMock(); var builder = new ContainerBuilder(); builder.Register(c => _searchBLFactory()).As <ISearchBL>().RequestScoped(); builder.Register(c => _pageBLFactory()).As <IPageBL>().RequestScoped(); builder.Register(_indexRebuilderMock).As <IIndexRebuilder>(); _hostInfo = DreamTestHelper.CreateRandomPortHost(new XDoc("config").Elem("apikey", Utils.Settings.ApiKey), builder.Build()); _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()); _hostInfo.Host.Self.At("load").With("name", "mindtouch.indexservice").Post(DreamMessage.Ok()); _deki = DreamTestHelper.CreateService(_hostInfo, Utils.Settings.DekiConfig); _search = _deki.AtLocalHost.At("site", "query"); }
public void GlobalSetup() { var config = new XDoc("config"); var builder = new ContainerBuilder(); _smtpClientFactory = new SmtpClientFactoryMock(); builder.Register(c => _smtpClientFactory).As <ISmtpClientFactory>().ServiceScoped(); _hostInfo = DreamTestHelper.CreateRandomPortHost(config, builder.Build()); _emailService = DreamTestHelper.CreateService( _hostInfo, "sid://mindtouch.com/2009/01/dream/email", "email", new XDoc("config") .Elem("apikey", "servicekey") .Elem("smtp-host", DEFAULT_HOST) ); _plug = _emailService.WithInternalKey().AtLocalHost; }
public DreamServiceInfo CreateCoreService() { var lucenePath = Path.Combine(Path.Combine(Path.GetTempPath(), StringUtil.CreateAlphaNumericKey(4)), "luceneindex"); Directory.CreateDirectory(lucenePath); var dekiConfig = new XDoc("config") .Elem("apikey", Utils.Settings.ApiKey) .Elem("path", "deki") .Elem("sid", "http://services.mindtouch.com/deki/draft/2006/11/dekiwiki") .Elem("deki-path", Utils.Settings.DekiPath) .Elem("imagemagick-convert-path", Utils.Settings.ImageMagickConvertPath) .Elem("imagemagick-identify-path", Utils.Settings.ImageMagickIdentifyPath) .Elem("princexml-path", Utils.Settings.PrinceXmlPath) .Elem("deki-resources-path", Utils.Settings.DekiResourcesPath) .Start("page-subscription") .Elem("accumulation-time", "0") .End() .Start("packageupdater").Attr("uri", Utils.Settings.PackageUpdaterMockUri).End() .Start("indexer").Attr("src", Utils.Settings.LuceneMockUri).End() .Elem("uri.page-subscription", Utils.Settings.PageSubscriptionMockUri) .Start("wikis") .Start("config") .Attr("id", "default") .Elem("host", "*") .Start("page-subscription") .Elem("from-address", "*****@*****.**") .End() .Elem("db-server", Utils.Settings.DbServer) .Elem("db-port", "3306") .Elem("db-catalog", Utils.Settings.DbCatalog) .Elem("db-user", Utils.Settings.DbUser) .Start("db-password") .Attr("hidden", "true").Value(Utils.Settings.DbPassword) .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() .Start("indexer") .Elem("path.store", lucenePath) .Elem("namespace-whitelist", "main, main_talk, user, user_talk") .End(); return(DreamTestHelper.CreateService(HostInfo, dekiConfig)); }
public void Execute(ExecutionPlan plan) { var service = DreamTestHelper.CreateService( _hostinfo, "sid://mindtouch.com/2007/12/dekiscript", "dekiscript", new XDoc("config").Elem("manifest", _manifestUri) ); foreach (var functionName in _manifest["function/name"]) { var name = functionName.AsText; _tester.Runtime.RegisterFunction(name, service.AtLocalHost.At(name)); } try { var expr = _tester.Parse(plan.Expr); var env = _tester.Runtime.CreateEnv(); env.Vars.Add(DekiScriptEnv.SAFEMODE, DekiScriptExpression.Constant(plan.Safe)); DekiScriptExpression result = _tester.Runtime.Evaluate(expr, plan.Safe ? DekiScriptEvalMode.EvaluateSafeMode : DekiScriptEvalMode.Evaluate, env); if (plan.TypedVerification != null) { Assert.AreEqual(plan.ExpectedType, result.GetType()); plan.TypedVerification(result); } else if (plan.DocVerification != null) { if (!(result is DekiScriptXml)) { Assert.Fail(string.Format("return type was '{0}' not DekiScriptXml", result.GetType())); } var doc = ((DekiScriptXml)result).Value; plan.DocVerification(doc); } else if (plan.StringVerification != null) { string value; if (result is DekiScriptString) { value = ((DekiScriptString)result).Value; } else if (result is DekiScriptXml) { value = ((DekiScriptXml)result).Value.ToString(); } else { value = result.ToString(); } plan.StringVerification(value, result.GetType()); } else { Assert.Fail("Execution completed without exception"); } } catch (Exception e) { if (plan.ExceptionVerification != null) { plan.ExceptionVerification(e); } else { throw; } } finally { service.WithPrivateKey().AtLocalHost.Delete(); } }
public void GlobalSetup() { _hostInfo = DreamTestHelper.CreateRandomPortHost(); _queueService = DreamTestHelper.CreateService(_hostInfo, "sid://mindtouch.com/2009/12/dream/queue", "queue", new XDoc("config").Elem("folder", Path.GetTempPath())); _plug = _queueService.WithInternalKey().AtLocalHost; }
public void Authtoken_recipients_always_get_what_they_want() { XUri mockDeki = new XUri("http://mock/deki"); int dekiCalled = 0; MockPlug.Register(mockDeki, delegate(Plug p, string v, XUri u, DreamMessage r, Result <DreamMessage> r2) { _log.DebugFormat("deki called at {0}", u); dekiCalled++; r2.Return(DreamMessage.Ok()); }); XUri mockAuthorized = new XUri("http://mock/authorized"); int authorizedCalled = 0; XDoc received = null; var authorizedResetEvent = new ManualResetEvent(false); MockPlug.Register(mockAuthorized, delegate(Plug p, string v, XUri u, DreamMessage r, Result <DreamMessage> r2) { authorizedCalled++; received = r.ToDocument(); authorizedResetEvent.Set(); r2.Return(DreamMessage.Ok()); }); XUri mockNotAuthorized = new XUri("http://mock/notauthorized"); int notAuthorizedCalled = 0; MockPlug.Register(mockNotAuthorized, delegate(Plug p, string v, XUri u, DreamMessage r, Result <DreamMessage> r2) { notAuthorizedCalled++; r2.Return(DreamMessage.Ok()); }); DreamServiceInfo serviceInfo = DreamTestHelper.CreateService( _hostInfo, "sid://mindtouch.com/dream/2008/10/pubsub", "authorization", new XDoc("config") .Elem("authtoken", "abc") .Elem("uri.deki", mockDeki) .Start("components") .Attr("context", "service") .Start("component") .Attr("implementation", typeof(DekiDispatcher).AssemblyQualifiedName) .Attr("type", typeof(IPubSubDispatcher).AssemblyQualifiedName) .End() .End() ); XDoc subForAuthorized = new XDoc("subscription-set") .Elem("uri.owner", mockAuthorized) .Start("subscription") .Attr("id", "1") .Elem("uri.resource", "http://mock/resource/*") .Elem("channel", "channel:///foo/*") .Start("recipient").Attr("authtoken", "abc").Elem("uri", mockAuthorized).End() .End(); DreamMessage result = serviceInfo.WithInternalKey().AtLocalHost.At("subscribers").PostAsync(subForAuthorized).Wait(); Assert.IsTrue(result.IsSuccessful); XDoc subForNotAuthorized = new XDoc("subscription-set") .Elem("uri.owner", mockNotAuthorized) .Start("subscription") .Attr("id", "1") .Elem("uri.resource", "http://mock/resource/*") .Elem("channel", "channel:///foo/*") .Start("recipient").Elem("uri", mockNotAuthorized).End() .End(); result = serviceInfo.WithInternalKey().AtLocalHost.At("subscribers").PostAsync(subForNotAuthorized).Wait(); Assert.IsTrue(result.IsSuccessful); XDoc msg = new XDoc("foop"); result = serviceInfo.WithInternalKey() .AtLocalHost .At("publish") .WithHeader(DreamHeaders.DREAM_EVENT_CHANNEL, "channel:///foo/bar") .WithHeader(DreamHeaders.DREAM_EVENT_ORIGIN, mockDeki.ToString()) .WithHeader(DreamHeaders.DREAM_EVENT_RESOURCE, "http://mock/resource/bar") .PostAsync(msg).Wait(); Assert.IsTrue(result.IsSuccessful); Wait.For(() => authorizedResetEvent.WaitOne(100, true), TimeSpan.FromSeconds(10)); Assert.AreEqual(0, dekiCalled); Assert.AreEqual(0, notAuthorizedCalled); Assert.AreEqual(1, authorizedCalled); Assert.AreEqual(msg, received); }
public void Uses_deki_to_prune_recipients() { XUri mockDeki = new XUri("http://mock/deki"); int dekiCalled = 0; int dekipage42authCalled = 0; bool dekiArgsGood = false; int dekipage43authCalled = 0; MockPlug.Register(mockDeki, delegate(Plug p, string v, XUri u, DreamMessage r, Result <DreamMessage> r2) { _log.DebugFormat("mockDeki called at: {0}", u); dekiCalled++; dekiArgsGood = false; List <int> users = new List <int>(); foreach (XDoc user in r.ToDocument()["user/@id"]) { users.Add(user.AsInt.Value); } if (users.Count == 4 && users.Contains(1) && users.Contains(2) && users.Contains(3) && users.Contains(4)) { dekiArgsGood = true; } DreamMessage msg = DreamMessage.Ok(); if (u.WithoutQuery() == mockDeki.At("pages", "42", "allowed")) { dekipage42authCalled++; msg = DreamMessage.Ok(new XDoc("users") .Start("user").Attr("id", 1).End() .Start("user").Attr("id", 2).End()); } else if (u.WithoutQuery() == mockDeki.At("pages", "43", "allowed")) { dekipage43authCalled++; msg = DreamMessage.Ok(new XDoc("users") .Start("user").Attr("id", 3).End() .Start("user").Attr("id", 4).End()); } r2.Return(msg); }); XUri mockRecipient = new XUri("http://mock/r1"); int mockRecipientCalled = 0; XDoc received = null; List <string> recipients = new List <string>(); AutoResetEvent are = new AutoResetEvent(false); MockPlug.Register(mockRecipient, delegate(Plug p, string v, XUri u, DreamMessage r, Result <DreamMessage> r2) { _log.DebugFormat("mockRecipient called at: {0}", u); mockRecipientCalled++; received = r.ToDocument(); recipients.Clear(); recipients.AddRange(r.Headers.DreamEventRecipients); are.Set(); r2.Return(DreamMessage.Ok()); }); DreamServiceInfo serviceInfo = DreamTestHelper.CreateService( _hostInfo, "sid://mindtouch.com/dream/2008/10/pubsub", "whitelist", new XDoc("config") .Elem("uri.deki", mockDeki) .Start("components") .Attr("context", "service") .Start("component") .Attr("implementation", typeof(DekiDispatcher).AssemblyQualifiedName) .Attr("type", typeof(IPubSubDispatcher).AssemblyQualifiedName) .End() .End() ); XDoc sub = new XDoc("subscription-set") .Elem("uri.owner", mockRecipient) .Start("subscription") .Attr("id", "1") .Elem("uri.resource", "http://mock/resource/x") .Elem("channel", "channel:///foo/*") .Elem("uri.proxy", mockRecipient) .Start("recipient").Attr("userid", "1").Elem("uri", "http://recipient/a").End() .Start("recipient").Attr("userid", "2").Elem("uri", "http://recipient/b").End() .Start("recipient").Attr("userid", "3").Elem("uri", "http://recipient/c").End() .Start("recipient").Attr("userid", "4").Elem("uri", "http://recipient/d").End() .End() .Start("subscription") .Attr("id", "2") .Elem("uri.resource", "http://mock/resource/y") .Elem("channel", "channel:///foo/*") .Elem("uri.proxy", mockRecipient) .Start("recipient").Attr("userid", "1").Elem("uri", "http://recipient/a").End() .Start("recipient").Attr("userid", "2").Elem("uri", "http://recipient/b").End() .Start("recipient").Attr("userid", "3").Elem("uri", "http://recipient/c").End() .Start("recipient").Attr("userid", "4").Elem("uri", "http://recipient/d").End() .End(); DreamMessage result = serviceInfo.WithInternalKey().AtLocalHost.At("subscribers").PostAsync(sub).Wait(); Assert.IsTrue(result.IsSuccessful); XDoc ev = new XDoc("event").Elem("pageid", 42); result = serviceInfo.WithInternalKey() .AtLocalHost .At("publish") .WithHeader(DreamHeaders.DREAM_EVENT_CHANNEL, "channel:///foo/bar") .WithHeader(DreamHeaders.DREAM_EVENT_ORIGIN, mockDeki.ToString()) .WithHeader(DreamHeaders.DREAM_EVENT_RESOURCE, "http://mock/resource/x") .PostAsync(ev).Wait(); Assert.IsTrue(result.IsSuccessful); Assert.IsTrue(are.WaitOne(500, true)); Assert.AreEqual(1, dekiCalled); Assert.AreEqual(1, dekipage42authCalled); Assert.IsTrue(dekiArgsGood); Assert.AreEqual(ev, received); Assert.AreEqual(2, recipients.Count); Assert.Contains("http://recipient/a", recipients); Assert.Contains("http://recipient/b", recipients); ev = new XDoc("event").Elem("pageid", 43); result = serviceInfo.WithInternalKey() .AtLocalHost .At("publish") .WithHeader(DreamHeaders.DREAM_EVENT_CHANNEL, "channel:///foo/bar") .WithHeader(DreamHeaders.DREAM_EVENT_ORIGIN, mockDeki.ToString()) .WithHeader(DreamHeaders.DREAM_EVENT_RESOURCE, "http://mock/resource/y") .PostAsync(ev).Wait(); Assert.IsTrue(result.IsSuccessful); Assert.IsTrue(are.WaitOne(5000, true)); Assert.AreEqual(2, dekiCalled); Assert.AreEqual(1, dekipage42authCalled); Assert.IsTrue(dekiArgsGood); Assert.AreEqual(ev, received); Assert.AreEqual(2, recipients.Count); Assert.Contains("http://recipient/c", recipients); Assert.Contains("http://recipient/d", recipients); }
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 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(); }