From ebfdfbe2453f6ae3e95db4ed9affb354f7bc73db Mon Sep 17 00:00:00 2001 From: Brian Picciano Date: Thu, 19 Jul 2018 20:11:21 +0000 Subject: [PATCH] mdatastore: implement basic initialization code --- env.test | 8 +++++ mdb/mdatastore/datastore.go | 43 +++++++++++++++++++++++++++ mdb/mdatastore/datastore_test.go | 50 ++++++++++++++++++++++++++++++++ mdb/mpubsub/pubsub.go | 4 +-- 4 files changed, 103 insertions(+), 2 deletions(-) create mode 100644 mdb/mdatastore/datastore.go create mode 100644 mdb/mdatastore/datastore_test.go diff --git a/env.test b/env.test index e1691a1..992bf74 100644 --- a/env.test +++ b/env.test @@ -1,5 +1,13 @@ +export CLOUDSDK_CORE_PROJECT="test" + if [ "$(ps aux | grep '[p]ubsub-emulator')" = "" ]; then echo "starting pubsub emulator" yes | gcloud beta emulators pubsub start >/dev/null 2>&1 & fi $(gcloud beta emulators pubsub env-init) + +if [ "$(ps aux | grep '[c]loud-datastore-emulator')" = "" ]; then + echo "starting datastore emulator" + yes | gcloud beta emulators datastore start >/dev/null 2>&1 & +fi +$(gcloud beta emulators datastore env-init) diff --git a/mdb/mdatastore/datastore.go b/mdb/mdatastore/datastore.go new file mode 100644 index 0000000..2da96ef --- /dev/null +++ b/mdb/mdatastore/datastore.go @@ -0,0 +1,43 @@ +// Package mdatastore implements connecting to Google's Datastore service and +// simplifying a number of interactions with it. +package mdatastore + +import ( + "context" + + "cloud.google.com/go/datastore" + "github.com/mediocregopher/mediocre-go-lib/m" + "github.com/mediocregopher/mediocre-go-lib/mcfg" + "github.com/mediocregopher/mediocre-go-lib/mdb" + "github.com/mediocregopher/mediocre-go-lib/mlog" +) + +// Datastore is a wrapper around a datastore client providing more +// functionality. +type Datastore struct { + *datastore.Client + + gce *mdb.GCE + log *mlog.Logger +} + +// Cfg configures and returns a Datastore instance which will be usable once +// StartRun is called on the passed in Cfg instance. +func Cfg(cfg *mcfg.Cfg) *Datastore { + cfg = cfg.Child("datastore") + var ds Datastore + ds.gce = mdb.CfgGCE(cfg) + ds.log = m.Log(cfg, &ds) + cfg.Start.Then(func(ctx context.Context) error { + ds.log.Info("connecting to datastore") + var err error + ds.Client, err = datastore.NewClient(ctx, ds.gce.Project, ds.gce.ClientOptions()...) + return mlog.ErrWithKV(err, &ds) + }) + return &ds +} + +// KV implements the mlog.KVer interface. +func (ds *Datastore) KV() mlog.KV { + return ds.gce.KV() +} diff --git a/mdb/mdatastore/datastore_test.go b/mdb/mdatastore/datastore_test.go new file mode 100644 index 0000000..fa7ec25 --- /dev/null +++ b/mdb/mdatastore/datastore_test.go @@ -0,0 +1,50 @@ +package mdatastore + +import ( + "context" + . "testing" + "time" + + "cloud.google.com/go/datastore" + "github.com/mediocregopher/mediocre-go-lib/mcfg" + "github.com/mediocregopher/mediocre-go-lib/mdb" + "github.com/mediocregopher/mediocre-go-lib/mrand" + "github.com/mediocregopher/mediocre-go-lib/mtest/massert" +) + +var testDS *Datastore + +func init() { + mdb.DefaultGCEProject = "test" + cfg := mcfg.New() + testDS = Cfg(cfg) + cfg.StartTestRun() +} + +// Requires datastore emulator to be running +func TestBasic(t *T) { + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + + name := mrand.Hex(8) + key := datastore.NameKey("testKind", name, nil) + key.Namespace = "TestBasic_" + mrand.Hex(8) + type valType struct { + A, B int + } + val := valType{ + A: mrand.Int(), + B: mrand.Int(), + } + + if _, err := testDS.Put(ctx, key, &val); err != nil { + t.Fatal(err) + } + + var val2 valType + if err := testDS.Get(ctx, key, &val2); err != nil { + t.Fatal(err) + } + + massert.Fatal(t, massert.Equal(val, val2)) +} diff --git a/mdb/mpubsub/pubsub.go b/mdb/mpubsub/pubsub.go index e5fb7d8..d228a0d 100644 --- a/mdb/mpubsub/pubsub.go +++ b/mdb/mpubsub/pubsub.go @@ -37,8 +37,8 @@ type PubSub struct { log *mlog.Logger } -// Cfg configures and returns a PubSub instance which will be usable once Run is -// called on the passed in Cfg instance +// Cfg configures and returns a PubSub instance which will be usable once +// StartRun is called on the passed in Cfg instance. func Cfg(cfg *mcfg.Cfg) *PubSub { cfg = cfg.Child("pubsub") var ps PubSub