code.cloudfoundry.org/diego-upgrade-stability-tests@v0.0.0-20210607152719-27f1f0151c54/upgrader_test.go (about)

     1  package dusts_test
     2  
     3  import (
     4  	"fmt"
     5  	"net"
     6  	"net/http"
     7  	"strconv"
     8  	"time"
     9  
    10  	auctioneerconfig "code.cloudfoundry.org/auctioneer/cmd/auctioneer/config"
    11  	bbsconfig "code.cloudfoundry.org/bbs/cmd/bbs/config"
    12  	"code.cloudfoundry.org/durationjson"
    13  	"code.cloudfoundry.org/inigo/helpers"
    14  	repconfig "code.cloudfoundry.org/rep/cmd/rep/config"
    15  	routeemitterconfig "code.cloudfoundry.org/route-emitter/cmd/route-emitter/config"
    16  
    17  	. "github.com/onsi/ginkgo"
    18  	. "github.com/onsi/gomega"
    19  	"github.com/tedsuo/ifrit"
    20  	"github.com/tedsuo/ifrit/ginkgomon"
    21  )
    22  
    23  func upgradeRep(idx int, process *ifrit.Process, modifyFuncs ...func(*repconfig.RepConfig)) {
    24  	msg := fmt.Sprintf("Upgrading cell %d", idx)
    25  	By(msg)
    26  
    27  	host, portStr, _ := net.SplitHostPort(ComponentMakerV0.Addresses().Rep)
    28  	port, err := strconv.Atoi(portStr)
    29  	ExpectWithOffset(1, err).NotTo(HaveOccurred())
    30  	port = port + 10*idx // TODO: this is a hack based on offsetPort in components.go
    31  
    32  	By(fmt.Sprintf("evacuating cell%d", idx))
    33  	addr := fmt.Sprintf("http://%s:%d/evacuate", host, port)
    34  	_, err = http.Post(addr, "", nil)
    35  	ExpectWithOffset(1, err).NotTo(HaveOccurred())
    36  	EventuallyWithOffset(1, (*process).Wait()).Should(Receive())
    37  
    38  	*process = ginkgomon.Invoke(ComponentMakerV1.RepN(idx, modifyFuncs...))
    39  }
    40  
    41  type Upgrader interface {
    42  	StartUp()
    43  	RollingUpgrade()
    44  	ShutDown()
    45  }
    46  
    47  type diegoGAUpgrader struct {
    48  	bbs          ifrit.Process
    49  	routeEmitter ifrit.Process
    50  	auctioneer   ifrit.Process
    51  	rep0         ifrit.Process
    52  	rep1         ifrit.Process
    53  }
    54  
    55  func NewGAUpgrader() Upgrader {
    56  	return &diegoGAUpgrader{}
    57  }
    58  
    59  func (ga *diegoGAUpgrader) StartUp() {
    60  	ga.bbs = ginkgomon.Invoke(ComponentMakerV0.BBS())
    61  	ga.routeEmitter = ginkgomon.Invoke(ComponentMakerV0.RouteEmitter())
    62  	ga.auctioneer = ginkgomon.Invoke(ComponentMakerV0.Auctioneer())
    63  	ga.rep0 = ginkgomon.Invoke(ComponentMakerV0.RepN(0))
    64  	ga.rep1 = ginkgomon.Invoke(ComponentMakerV0.RepN(1))
    65  }
    66  
    67  func (ga *diegoGAUpgrader) RollingUpgrade() {
    68  	By("Upgrading the BBS")
    69  	ginkgomon.Interrupt(ga.bbs, 5*time.Second)
    70  	skipLocket := func(cfg *bbsconfig.BBSConfig) {
    71  		cfg.LocksLocketEnabled = false
    72  		cfg.CellRegistrationsLocketEnabled = false
    73  	}
    74  	ga.bbs = ginkgomon.Invoke(ComponentMakerV1.BBS(skipLocket))
    75  
    76  	By("Upgrading the Auctioneer")
    77  	ginkgomon.Interrupt(ga.auctioneer, 5*time.Second)
    78  	ga.auctioneer = ginkgomon.Invoke(ComponentMakerV1.Auctioneer(func(cfg *auctioneerconfig.AuctioneerConfig) {
    79  		cfg.LocksLocketEnabled = false
    80  	}))
    81  
    82  	By("Upgrading the Route Emitter")
    83  	ginkgomon.Interrupt(ga.routeEmitter, 5*time.Second)
    84  	ga.routeEmitter = ginkgomon.Invoke(ComponentMakerV1.RouteEmitter())
    85  
    86  	upgradeRep(0, &ga.rep0)
    87  
    88  	upgradeRep(1, &ga.rep1)
    89  }
    90  
    91  func (ga *diegoGAUpgrader) ShutDown() {
    92  	helpers.StopProcesses(
    93  		ga.routeEmitter,
    94  		ga.auctioneer,
    95  		ga.rep0,
    96  		ga.rep1,
    97  		ga.bbs,
    98  	)
    99  }
   100  
   101  type diegoLocketLocalREUpgrader struct {
   102  	bbs              ifrit.Process
   103  	routeEmitter0    ifrit.Process
   104  	routeEmitter1    ifrit.Process
   105  	auctioneer       ifrit.Process
   106  	rep0             ifrit.Process
   107  	rep1             ifrit.Process
   108  	locket           ifrit.Process
   109  	cell0ID, cell1ID string
   110  }
   111  
   112  func NewLocketLocalREUpgrader() *diegoLocketLocalREUpgrader {
   113  	return &diegoLocketLocalREUpgrader{}
   114  }
   115  
   116  func (lre *diegoLocketLocalREUpgrader) StartUp() {
   117  	lre.locket = ginkgomon.Invoke(ComponentMakerV0.Locket())
   118  
   119  	lre.bbs = ginkgomon.Invoke(ComponentMakerV0.BBS())
   120  	lre.auctioneer = ginkgomon.Invoke(ComponentMakerV0.Auctioneer())
   121  
   122  	lre.rep0 = ginkgomon.Invoke(ComponentMakerV0.RepN(0, func(cfg *repconfig.RepConfig) {
   123  		cfg.EvacuationTimeout = durationjson.Duration(10 * time.Second)
   124  		lre.cell0ID = cfg.CellID
   125  	}))
   126  	lre.rep1 = ginkgomon.Invoke(ComponentMakerV0.RepN(1, func(cfg *repconfig.RepConfig) {
   127  		cfg.EvacuationTimeout = durationjson.Duration(10 * time.Second)
   128  		lre.cell1ID = cfg.CellID
   129  	}))
   130  
   131  	lre.routeEmitter0 = ginkgomon.Invoke(ComponentMakerV0.RouteEmitterN(0, func(cfg *routeemitterconfig.RouteEmitterConfig) {
   132  		cfg.CellID = lre.cell0ID
   133  	}))
   134  	lre.routeEmitter1 = ginkgomon.Invoke(ComponentMakerV0.RouteEmitterN(1, func(cfg *routeemitterconfig.RouteEmitterConfig) {
   135  		cfg.CellID = lre.cell1ID
   136  	}))
   137  }
   138  
   139  func (lre *diegoLocketLocalREUpgrader) ShutDown() {
   140  	helpers.StopProcesses(
   141  		lre.routeEmitter0,
   142  		lre.routeEmitter1,
   143  		lre.auctioneer,
   144  		lre.rep0,
   145  		lre.rep1,
   146  		lre.bbs,
   147  		lre.locket,
   148  	)
   149  }
   150  
   151  func (lre *diegoLocketLocalREUpgrader) RollingUpgrade() {
   152  	By("Upgrading Locket")
   153  	ginkgomon.Interrupt(lre.locket, 5*time.Second)
   154  	lre.locket = ginkgomon.Invoke(ComponentMakerV1.Locket())
   155  
   156  	By("Downgrading Locket")
   157  	ginkgomon.Interrupt(lre.locket, 5*time.Second)
   158  	lre.locket = ginkgomon.Invoke(ComponentMakerV0.Locket())
   159  
   160  	By("Upgrading the BBS")
   161  	ginkgomon.Interrupt(lre.bbs, 5*time.Second)
   162  	lre.bbs = ginkgomon.Invoke(ComponentMakerV1.BBS())
   163  
   164  	By("Upgrading Locket")
   165  	ginkgomon.Interrupt(lre.locket, 5*time.Second)
   166  	lre.locket = ginkgomon.Invoke(ComponentMakerV1.Locket())
   167  
   168  	By("Upgrading the Auctioneer")
   169  	ginkgomon.Interrupt(lre.auctioneer, 5*time.Second)
   170  	lre.auctioneer = ginkgomon.Invoke(ComponentMakerV1.Auctioneer())
   171  
   172  	setEvacuationTimeout := func(cfg *repconfig.RepConfig) {
   173  		cfg.EvacuationTimeout = durationjson.Duration(10 * time.Second)
   174  	}
   175  
   176  	upgradeRep(0, &lre.rep0, setEvacuationTimeout)
   177  	By("Upgrading Route Emitter 0")
   178  	ginkgomon.Interrupt(lre.routeEmitter0, 5*time.Second)
   179  	lre.routeEmitter0 = ginkgomon.Invoke(ComponentMakerV1.RouteEmitterN(0, func(cfg *routeemitterconfig.RouteEmitterConfig) {
   180  		cfg.CellID = lre.cell0ID
   181  	}))
   182  
   183  	upgradeRep(1, &lre.rep1, setEvacuationTimeout)
   184  	By("Upgrading Route Emitter 1")
   185  	ginkgomon.Interrupt(lre.routeEmitter1, 5*time.Second)
   186  	lre.routeEmitter1 = ginkgomon.Invoke(ComponentMakerV1.RouteEmitterN(1, func(cfg *routeemitterconfig.RouteEmitterConfig) {
   187  		cfg.CellID = lre.cell1ID
   188  	}))
   189  }