github.com/manicqin/nomad@v0.9.5/nomad/testing.go (about)

     1  package nomad
     2  
     3  import (
     4  	"fmt"
     5  	"math/rand"
     6  	"net"
     7  	"sync/atomic"
     8  	"time"
     9  
    10  	testing "github.com/mitchellh/go-testing-interface"
    11  	"github.com/pkg/errors"
    12  
    13  	"github.com/hashicorp/nomad/command/agent/consul"
    14  	"github.com/hashicorp/nomad/helper/freeport"
    15  	"github.com/hashicorp/nomad/helper/pluginutils/catalog"
    16  	"github.com/hashicorp/nomad/helper/pluginutils/singleton"
    17  	"github.com/hashicorp/nomad/helper/testlog"
    18  	"github.com/hashicorp/nomad/nomad/mock"
    19  	"github.com/hashicorp/nomad/nomad/structs"
    20  	"github.com/hashicorp/nomad/version"
    21  )
    22  
    23  var (
    24  	nodeNumber uint32 = 0
    25  )
    26  
    27  func TestACLServer(t testing.T, cb func(*Config)) (*Server, *structs.ACLToken, func()) {
    28  	server, cleanup := TestServer(t, func(c *Config) {
    29  		c.ACLEnabled = true
    30  		if cb != nil {
    31  			cb(c)
    32  		}
    33  	})
    34  	token := mock.ACLManagementToken()
    35  	err := server.State().BootstrapACLTokens(1, 0, token)
    36  	if err != nil {
    37  		t.Fatalf("failed to bootstrap ACL token: %v", err)
    38  	}
    39  	return server, token, cleanup
    40  }
    41  
    42  func TestServer(t testing.T, cb func(*Config)) (*Server, func()) {
    43  	// Setup the default settings
    44  	config := DefaultConfig()
    45  	config.Logger = testlog.HCLogger(t)
    46  	config.Build = version.Version + "+unittest"
    47  	config.DevMode = true
    48  	nodeNum := atomic.AddUint32(&nodeNumber, 1)
    49  	config.NodeName = fmt.Sprintf("nomad-%03d", nodeNum)
    50  
    51  	// Tighten the Serf timing
    52  	config.SerfConfig.MemberlistConfig.BindAddr = "127.0.0.1"
    53  	config.SerfConfig.MemberlistConfig.SuspicionMult = 2
    54  	config.SerfConfig.MemberlistConfig.RetransmitMult = 2
    55  	config.SerfConfig.MemberlistConfig.ProbeTimeout = 50 * time.Millisecond
    56  	config.SerfConfig.MemberlistConfig.ProbeInterval = 100 * time.Millisecond
    57  	config.SerfConfig.MemberlistConfig.GossipInterval = 100 * time.Millisecond
    58  
    59  	// Tighten the Raft timing
    60  	config.RaftConfig.LeaderLeaseTimeout = 50 * time.Millisecond
    61  	config.RaftConfig.HeartbeatTimeout = 50 * time.Millisecond
    62  	config.RaftConfig.ElectionTimeout = 50 * time.Millisecond
    63  	config.RaftTimeout = 500 * time.Millisecond
    64  
    65  	// Disable Vault
    66  	f := false
    67  	config.VaultConfig.Enabled = &f
    68  
    69  	// Squelch output when -v isn't specified
    70  	config.LogOutput = testlog.NewWriter(t)
    71  
    72  	// Tighten the autopilot timing
    73  	config.AutopilotConfig.ServerStabilizationTime = 100 * time.Millisecond
    74  	config.ServerHealthInterval = 50 * time.Millisecond
    75  	config.AutopilotInterval = 100 * time.Millisecond
    76  
    77  	// Set the plugin loaders
    78  	config.PluginLoader = catalog.TestPluginLoader(t)
    79  	config.PluginSingletonLoader = singleton.NewSingletonLoader(config.Logger, config.PluginLoader)
    80  
    81  	// Disable consul autojoining: tests typically join servers directly
    82  	config.ConsulConfig.ServerAutoJoin = &f
    83  
    84  	// Invoke the callback if any
    85  	if cb != nil {
    86  		cb(config)
    87  	}
    88  
    89  	// Enable raft as leader if we have bootstrap on
    90  	config.RaftConfig.StartAsLeader = !config.DevDisableBootstrap
    91  
    92  	catalog := consul.NewMockCatalog(config.Logger)
    93  
    94  	for i := 10; i >= 0; i-- {
    95  		// Get random ports, need to cleanup later
    96  		ports := freeport.MustTake(2)
    97  
    98  		config.RPCAddr = &net.TCPAddr{
    99  			IP:   []byte{127, 0, 0, 1},
   100  			Port: ports[0],
   101  		}
   102  		config.SerfConfig.MemberlistConfig.BindPort = ports[1]
   103  
   104  		// Create server
   105  		server, err := NewServer(config, catalog)
   106  		if err == nil {
   107  			return server, func() {
   108  				ch := make(chan error)
   109  				go func() {
   110  					defer close(ch)
   111  
   112  					// Shutdown server
   113  					err := server.Shutdown()
   114  					if err != nil {
   115  						ch <- errors.Wrap(err, "failed to shutdown server")
   116  					}
   117  
   118  					freeport.Return(ports)
   119  				}()
   120  
   121  				select {
   122  				case e := <-ch:
   123  					if e != nil {
   124  						t.Fatal(e.Error())
   125  					}
   126  				case <-time.After(1 * time.Minute):
   127  					t.Fatal("timed out while shutting down server")
   128  				}
   129  			}
   130  		} else if i == 0 {
   131  			freeport.Return(ports)
   132  			t.Fatalf("err: %v", err)
   133  		} else {
   134  			if server != nil {
   135  				_ = server.Shutdown()
   136  				freeport.Return(ports)
   137  			}
   138  			wait := time.Duration(rand.Int31n(2000)) * time.Millisecond
   139  			time.Sleep(wait)
   140  		}
   141  	}
   142  
   143  	return nil, nil
   144  }
   145  
   146  func TestJoin(t testing.T, s1 *Server, other ...*Server) {
   147  	addr := fmt.Sprintf("127.0.0.1:%d",
   148  		s1.config.SerfConfig.MemberlistConfig.BindPort)
   149  	for _, s2 := range other {
   150  		if num, err := s2.Join([]string{addr}); err != nil {
   151  			t.Fatalf("err: %v", err)
   152  		} else if num != 1 {
   153  			t.Fatalf("bad: %d", num)
   154  		}
   155  	}
   156  }