code: func (c *testCluster) RemoveNode(id string, graceful bool) error {
  	node, ok := c.nodes[id]
  	if !ok {
  		return fmt.Errorf("remove node: node %s not found", id)
  	}
  	// demote before removal
  	if node.IsManager() {
  		if err := c.SetNodeRole(id, api.NodeRoleWorker); err != nil {
  			return fmt.Errorf("demote manager: %v", err)
  		}
  
  	}
  	if err := node.Stop(); err != nil {
  		return err
  	}
  	delete(c.nodes, id)
  	if graceful {
  		if err := testutils.PollFuncWithTimeout(nil, func() error {
  			resp, err := c.api.GetNode(context.Background(), &api.GetNodeRequest{NodeID: id})
  			if err != nil {
  				return fmt.Errorf("get node: %v", err)
  			}
  			if resp.Node.Status.State != api.NodeStatus_DOWN {
  				return fmt.Errorf("node %s is still not down", id)
  			}
  			return nil
  		}, opsTimeout); err != nil {
  			return err
  		}
  	}
  	if _, err := c.api.RemoveNode(context.Background(), &api.RemoveNodeRequest{NodeID: id, Force: !graceful}); err != nil {
  		return fmt.Errorf("remove node: %v", err)
  	}
  	return nil
  }
docs: // RemoveNode removes node entirely. It tries to demote managers.