Embedded EventStore, I tip my hat to you sir

I just wanted to take a minute to say THANK YOU for the EventStore.ClientAPI.Embedded. It has made my integration tests so much easier and configuration-free.

Here’s how I’m using it with integration tests. Sorry / You’re welcome F#

namespace TestingNamespace

open System.Net

open EventStore.Core

open EventStore.ClientAPI.Embedded

open EventStore.ClientAPI

type EmbeddedEventStore = {

VNode: ClusterVNode;

Connection: IEventStoreConnection;

}

module TestEventStore =

let get () =

    let noIp = new IPEndPoint(IPAddress.None, 0)

    let vnode = 

        EmbeddedVNodeBuilder

            .AsSingleNode()

            .RunInMemory()

            .WithExternalTcpOn(noIp)

            .WithInternalTcpOn(noIp)

            .WithExternalHttpOn(noIp)

            .WithInternalHttpOn(noIp)

            .Build()

    vnode.Start()

    let connection = EmbeddedEventStoreConnection.Create(vnode)

    {VNode = vnode; Connection = connection;}

let stop testEs =

    testEs.Connection.Close()

    testEs.VNode.Stop()

``

A global event store for testing, MSTest version

namespace TestingNamespace

open Microsoft.VisualStudio.TestTools.UnitTesting

[]

type GlobalTestEventStore () =

[<DefaultValue>]

static val mutable private _testEs : EmbeddedEventStore

[<DefaultValue>]

static val mutable private _closedEs : EmbeddedEventStore

static member Connection with get () = GlobalTestEventStore._testEs.Connection

static member ClosedConnection with get () = GlobalTestEventStore._closedEs.Connection

[<AssemblyInitialize>]

static member StartTestEventStore(context:TestContext) =

    GlobalTestEventStore._testEs <- TestEventStore.get ()

    GlobalTestEventStore._closedEs <- TestEventStore.get ()

    TestEventStore.stop GlobalTestEventStore._closedEs

[<AssemblyCleanup>]

static member StopTestEventStore() =

    TestEventStore.stop GlobalTestEventStore._testEs

``

ClosedConnection is for testing error cases where the EventStore is not available.

One minor thing that would clear up a bunch of warnings on my builds is a way to synchronously wait for the VNode to shut down. ClusterVNode.Stop() only queues a shutdown, doesn’t wait for it. Therefore various event callbacks after cleanup is done cause AppDomainUnloaded exceptions when my builds run tests. Not a big deal, though.

This one? :slight_smile: https://github.com/EventStore/EventStore/blob/dev/src/EventStore.Core/ClusterVNode.cs#L545

Awesome! Can’t wait to see it released. :slight_smile:

guess its been in dev for a while but not hit binaries yet :slight_smile:

Is there anything similar for the Jvm client?

It could never exist unless you want to rewrite the entire backend for the jvm?

Well flapdoodle for mongodb does a good job of it.

https://github.com/flapdoodle-oss/de.flapdoodle.embed.mongo

I might do some research as to what embedded actually is. This is
nothing like embedded.

Its a very easy way to write integration tests against mongodb. Something similar for eventstore would be extremely useful.

Do you not notice they are "platform neutral" so long as the platform
is the JVM? Our embedded oddly works in the same way

"Other ways to use Embedded MongoDB

in a Maven build using embedmongo-maven-plugin
in a Clojure/Leiningen project using lein-embongo
in a Gradle build using gradle-mongo-plugin
in a Scala/specs2 specification using specs2-embedmongo
in Scala tests using scalatest-embedmongo"

How would I use "embedded mongo from say the CLR"? Oh wait this sounds
like why we don't support embedded on the jvm.

For unit testing from the jvm you can also just run the node with
--mem-db which will give you an in memory database to benchmark with.

Embedded is not limited to the use of "for unit testing".

Cheers,

Greg

Embedded is not limited to the use of “for unit testing”.

Yes, in fact we are excited at the deployment options this enables us. Thank you! :slight_smile:

I tried this code with 3.0.3 and it didn’t work, though it did work with the default ports. I get a log message that says “The requested address is not valid in its context”. The error seems to be in starting the HTTP server.

Here is output from logs:

2015-04-10 12:31:03.732 -04:00 [Information] ========== [“255.255.255.255:0”] SYSTEM INIT…
2015-04-10 12:31:03.779 -04:00 [Information] Starting “Normal” TCP listening on TCP endpoint: “255.255.255.255:0”.
2015-04-10 12:31:03.779 -04:00 [Information] TableIndex initialization…
2015-04-10 12:31:03.794 -04:00 [Information] Failed to listen on TCP endpoint: “255.255.255.255:0”.
2015-04-10 12:31:03.794 -04:00 [Information] ReadIndex building…
2015-04-10 12:31:03.794 -04:00 [Error] Exiting with exit code: 1.
Exit reason: The requested address is not valid in its context
2015-04-10 12:31:03.794 -04:00 [Information] Starting HTTP server on [“http://255.255.255.255:0/”]…
2015-04-10 12:31:03.841 -04:00 [Fatal] Failed to start http server
System.ObjectDisposedException: Cannot access a disposed object.
Object name: ‘System.Net.HttpListener’.
at System.Net.HttpListener.CheckDisposed()
at System.Net.HttpListener.BeginGetContext(AsyncCallback callback, Object state)
at EventStore.Transport.Http.Server.HttpAsyncServer.TryStart()
2015-04-10 12:31:03.841 -04:00 [Information] ========== [“255.255.255.255:0”] Service ‘“StorageReader”’ initialized.
2015-04-10 12:31:03.857 -04:00 [Information] ========== [“255.255.255.255:0”] Service ‘“StorageWriter”’ initialized.
2015-04-10 12:31:03.857 -04:00 [Information] ========== [“255.255.255.255:0”] Service ‘“StorageChaser”’ initialized.
2015-04-10 12:31:03.857 -04:00 [Information] ========== [“255.255.255.255:0”] SYSTEM START…
2015-04-10 12:31:03.857 -04:00 [Information] ========== [“255.255.255.255:0”] IS UNKNOWN!!! WHOA!!!
2015-04-10 12:31:03.873 -04:00 [Information] ELECTIONS: (V=0) DONE. ELECTED MASTER = “255.255.255.255:0,{1bfc6ac9-7598-4db4-b5b8-77c3b81dd55f}”. ME=“255.255.255.255:0,{1bfc6ac9-7598-4db4-b5b8-77c3b81dd55f}”.
2015-04-10 12:31:03.873 -04:00 [Information] ========== [“255.255.255.255:0”] PRE-MASTER STATE, WAITING FOR CHASER TO CATCH UP…
2015-04-10 12:31:03.873 -04:00 [Information] ========== [“255.255.255.255:0”] IS MASTER!!! SPARTA!!!
2015-04-10 12:31:04.029 -04:00 [Information] ‘admin’ user account has been created

I just checked, and I’m using 3.0.2. I went to try to upgrade to 3.0.3 and verify this crash, but apparently 3.0.2 is the latest one on NuGet.

I mis-spoke I used the 3.0.2 package.

can you show your wireup code please?