github.com/aminovpavel/nomad@v0.11.8/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 config.BootstrapExpect = 1 49 nodeNum := atomic.AddUint32(&nodeNumber, 1) 50 config.NodeName = fmt.Sprintf("nomad-%03d", nodeNum) 51 52 // Tighten the Serf timing 53 config.SerfConfig.MemberlistConfig.BindAddr = "127.0.0.1" 54 config.SerfConfig.MemberlistConfig.SuspicionMult = 2 55 config.SerfConfig.MemberlistConfig.RetransmitMult = 2 56 config.SerfConfig.MemberlistConfig.ProbeTimeout = 50 * time.Millisecond 57 config.SerfConfig.MemberlistConfig.ProbeInterval = 100 * time.Millisecond 58 config.SerfConfig.MemberlistConfig.GossipInterval = 100 * time.Millisecond 59 60 // Tighten the Raft timing 61 config.RaftConfig.LeaderLeaseTimeout = 50 * time.Millisecond 62 config.RaftConfig.HeartbeatTimeout = 50 * time.Millisecond 63 config.RaftConfig.ElectionTimeout = 50 * time.Millisecond 64 config.RaftTimeout = 500 * time.Millisecond 65 66 // Disable Vault 67 f := false 68 config.VaultConfig.Enabled = &f 69 70 // Squelch output when -v isn't specified 71 config.LogOutput = testlog.NewWriter(t) 72 73 // Tighten the autopilot timing 74 config.AutopilotConfig.ServerStabilizationTime = 100 * time.Millisecond 75 config.ServerHealthInterval = 50 * time.Millisecond 76 config.AutopilotInterval = 100 * time.Millisecond 77 78 // Set the plugin loaders 79 config.PluginLoader = catalog.TestPluginLoader(t) 80 config.PluginSingletonLoader = singleton.NewSingletonLoader(config.Logger, config.PluginLoader) 81 82 // Disable consul autojoining: tests typically join servers directly 83 config.ConsulConfig.ServerAutoJoin = &f 84 85 // Invoke the callback if any 86 if cb != nil { 87 cb(config) 88 } 89 90 catalog := consul.NewMockCatalog(config.Logger) 91 92 acls := consul.NewMockACLsAPI(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, acls) 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 }