repo_description: Nomad is an easy-to-use, flexible, and performant workload orchestrator that can deploy a mix of microservice, batch, containerized, and non-containerized applications. Nomad is easy to operate and scale and has native Consul and Vault integrations.
code: // Copyright IBM Corp. 2015, 2025
  // SPDX-License-Identifier: MPL-2.0
  
  package api
  
  import (
  	"testing"
  	"time"
  
  	"github.com/hashicorp/nomad/api/internal/testutil"
  	"github.com/shoenig/test/must"
  )
  
  func TestNodeMeta_Apply(t *testing.T) {
  	testutil.Parallel(t)
  
  	cb := func(c *testutil.TestServerConfig) {
  		c.DevMode = true
  	}
  	c, s := makeClient(t, nil, cb)
  	defer s.Stop()
  
  	nodeID := oneNodeFromNodeList(t, c.Nodes()).ID
  
  	node, _, err := c.Nodes().Info(nodeID, nil)
  	must.NoError(t, err)
  	must.Greater(t, 1, len(node.Meta),
  		must.Sprintf("expected more Node.Meta by default: %#v", node.Meta))
  
  	metaResp, err := c.Nodes().Meta().Read(node.ID, nil)
  	must.NoError(t, err)
  	must.MapEq(t, node.Meta, metaResp.Meta)
  	must.MapEq(t, node.Meta, metaResp.Static)
  	must.MapEmpty(t, metaResp.Dynamic)
  
  	staticKey := ""
  	for staticKey = range node.Meta {
  		break
  	}
  
  	req := &NodeMetaApplyRequest{
  		NodeID: node.ID,
  		Meta: map[string]*string{
  			staticKey: nil,
  			"foo":     pointerOf("bar"),
  		},
  	}
  
  	metaResp, err = c.Nodes().Meta().Apply(req, nil)
  	must.NoError(t, err)
  	must.MapEq(t, req.Meta, metaResp.Dynamic)
  	must.MapEq(t, node.Meta, metaResp.Static)
  	must.MapNotContainsKey(t, metaResp.Meta, staticKey)
  	must.Eq(t, "bar", metaResp.Meta["foo"])
  
  	// Wait up to 10s (plus buffer) for node to re-register
  	deadline := time.Now().Add(11 * time.Second)
  	found := false
  	for !found && time.Now().Before(deadline) {
  		node, _, err = c.Nodes().Info(node.ID, nil)
  		must.NoError(t, err)
  		found = node.Meta["foo"] == "bar"
  		time.Sleep(100 * time.Millisecond)
  	}
  	must.True(t, found)
  }
  