func (adapter *ETCDStoreAdapter) makeStoreNode(etcdNode *etcd.Node) *storeadapter.StoreNode { if etcdNode == nil { return nil } if etcdNode.Dir { node := storeadapter.StoreNode{ Key: etcdNode.Key, Dir: true, Value: []byte{}, ChildNodes: []storeadapter.StoreNode{}, TTL: uint64(etcdNode.TTL), Index: uint64(etcdNode.ModifiedIndex), } for _, child := range etcdNode.Nodes { node.ChildNodes = append(node.ChildNodes, *adapter.makeStoreNode(child)) } return &node } else { return &storeadapter.StoreNode{ Key: etcdNode.Key, Value: []byte(etcdNode.Value), TTL: uint64(etcdNode.TTL), Index: uint64(etcdNode.ModifiedIndex), } } }
func (adapter *ETCDStoreAdapter) MaintainNode(storeNode storeadapter.StoreNode) (<-chan bool, chan (chan bool), error) { if storeNode.TTL == 0 { return nil, nil, storeadapter.ErrorInvalidTTL } if len(storeNode.Value) == 0 { guid, err := uuid.NewV4() if err != nil { return nil, nil, err } storeNode.Value = []byte(guid.String()) } releaseNode := make(chan chan bool) nodeStatus := make(chan bool) go adapter.maintainNode(storeNode, nodeStatus, releaseNode) return nodeStatus, releaseNode, nil }
}) }) It("Stops", func() { finder.Stop() Eventually(stopChan).Should(BeClosed()) }) }) Context("with a real etcd", func() { var ( storeAdapter storeadapter.StoreAdapter node storeadapter.StoreNode updateNode storeadapter.StoreNode updateCallback func(all map[string]string, preferred map[string]string) callbackCount *int32 preferredCallback func(key string) bool preferredCount *int32 ) BeforeEach(func() { workPool, err := workpool.NewWorkPool(10) Expect(err).NotTo(HaveOccurred()) options := &etcdstoreadapter.ETCDOptions{ ClusterUrls: etcdRunner.NodeURLS(), } storeAdapter, err = etcdstoreadapter.New(options, workPool) Expect(err).NotTo(HaveOccurred())
finder.Start() }) It("watches and lists both roots", func() { Eventually(mockStoreAdapter.ListRecursivelyInput.key).Should(Receive(Equal(dopplerservice.META_ROOT))) Eventually(mockStoreAdapter.WatchInput.key).Should(Receive(Equal(dopplerservice.META_ROOT))) Eventually(mockStoreAdapter.ListRecursivelyInput.key).Should(Receive(Equal(dopplerservice.LEGACY_ROOT))) Eventually(mockStoreAdapter.WatchInput.key).Should(Receive(Equal(dopplerservice.LEGACY_ROOT))) Consistently(mockStoreAdapter.WatchCalled).Should(HaveLen(2)) }) }) Describe("Next (initialization)", func() { var ( metaNode storeadapter.StoreNode legacyNode storeadapter.StoreNode ) BeforeEach(func() { metaNode = storeadapter.StoreNode{} legacyNode = storeadapter.StoreNode{} close(mockStoreAdapter.WatchOutput.errors) close(mockStoreAdapter.WatchOutput.events) close(mockStoreAdapter.WatchOutput.stop) close(mockStoreAdapter.ListRecursivelyOutput.ret1) }) JustBeforeEach(func() { mockStoreAdapter.ListRecursivelyOutput.ret0 <- metaNode