go.ligato.io/vpp-agent/v3@v3.5.0/examples/kvscheduler/mock_plugins/scenario/scenario.go (about)

     1  //  Copyright (c) 2019 Cisco and/or its affiliates.
     2  //
     3  //  Licensed under the Apache License, Version 2.0 (the "License");
     4  //  you may not use this file except in compliance with the License.
     5  //  You may obtain a copy of the License at:
     6  //
     7  //      http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  //  Unless required by applicable law or agreed to in writing, software
    10  //  distributed under the License is distributed on an "AS IS" BASIS,
    11  //  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  //  See the License for the specific language governing permissions and
    13  //  limitations under the License.
    14  
    15  package scenario
    16  
    17  import (
    18  	"bufio"
    19  	"fmt"
    20  	"log"
    21  	"os"
    22  	"strings"
    23  	"time"
    24  
    25  	"go.ligato.io/vpp-agent/v3/client"
    26  	kvs "go.ligato.io/vpp-agent/v3/plugins/kvscheduler/api"
    27  	"go.ligato.io/vpp-agent/v3/proto/ligato/kvscheduler"
    28  )
    29  
    30  const graphURL = "http://localhost:9191/scheduler/graph"
    31  
    32  const (
    33  	InfoMsgColor     = "\033[1;34m%s\033[0m\n"
    34  	NoticeMsgColor   = "\033[1;35m%s\033[0m\n"
    35  	NotifMsgColor    = "\033[1;33m%s\033[0m\n"
    36  	ErrorMsgColor    = "\033[1;31m%s\033[0m\n"
    37  	InputReqMsgColor = "\033[0;32m%s\033[0m\n"
    38  	DebugMsgColor    = "\033[0;36m%s\033[0m\n"
    39  )
    40  
    41  // Run runs a scenario selected by the user.
    42  func Run(kv kvs.KVScheduler, setLogging func(debugMode bool)) {
    43  	time.Sleep(300 * time.Millisecond) // give agent logs time to get printed
    44  	defer func() {
    45  		fmt.Printf(InfoMsgColor, "The example scenario has finalized, the agent can be now terminated with CTRL-C.")
    46  		fmt.Printf(InfoMsgColor, "But while the agent is still running, the REST API of KVScheduler can be explored.")
    47  		fmt.Printf(InfoMsgColor, "Learn more from docs/kvscheduler/kvscheduler.md, section \"REST API\"")
    48  	}()
    49  
    50  	// let the user to select the scenario to run
    51  	scenarioFnc := func() {}
    52  	debugLog := true
    53  	scanner := bufio.NewScanner(os.Stdin)
    54  	fmt.Println("")
    55  	fmt.Printf(InputReqMsgColor, "Please select the example scenario to run: ")
    56  	fmt.Printf(InputReqMsgColor, "1) BD-interface binding and FIB are pending after the first resync, but become ready after an update")
    57  	fmt.Printf(InputReqMsgColor, "2) BD-interface binding and FIB are unconfigured and set as pending after an update")
    58  	fmt.Printf(InputReqMsgColor, "3) Update transaction with invalid interface MAC address is reverted")
    59  	fmt.Printf(InputReqMsgColor, "4) Invalid interface configuration fixed in the next Update transaction")
    60  	fmt.Printf(InputReqMsgColor, "5) Change of the interface type performed via re-creation")
    61  	fmt.Printf(InputReqMsgColor, "6) Failed interface creation fixed by subsequent Retry")
    62  	fmt.Printf(InputReqMsgColor, "7) Run performance test")
    63  inputLoop:
    64  	for {
    65  		fmt.Print("--> ")
    66  		scanner.Scan()
    67  		input := scanner.Text()
    68  		switch input {
    69  		case "1":
    70  			scenarioFnc = PendingAfterResync
    71  			break inputLoop
    72  		case "2":
    73  			scenarioFnc = PendingAfterChange
    74  			break inputLoop
    75  		case "3":
    76  			scenarioFnc = RevertedChange
    77  			break inputLoop
    78  		case "4":
    79  			scenarioFnc = InvalidConfigFixedWithUpdate
    80  			break inputLoop
    81  		case "5":
    82  			scenarioFnc = InterfaceRecreation
    83  			break inputLoop
    84  		case "6":
    85  			scenarioFnc = FailureFixedWithRetry
    86  			break inputLoop
    87  		case "7":
    88  			debugLog = false
    89  			scenarioFnc = PerfTest
    90  			break inputLoop
    91  		default:
    92  			fmt.Printf(ErrorMsgColor, "Invalid option!")
    93  			continue
    94  		}
    95  	}
    96  
    97  	setLogging(debugLog)
    98  	if debugLog {
    99  		// watch and inform about value status updates
   100  		ch := make(chan *kvscheduler.BaseValueStatus, 100)
   101  		kv.WatchValueStatus(ch, nil)
   102  		go watchValueStatus(ch)
   103  	}
   104  
   105  	// start the selected scenario
   106  	scenarioFnc()
   107  }
   108  
   109  // watchValueStatus informs about value status updates.
   110  func watchValueStatus(ch <-chan *kvscheduler.BaseValueStatus) {
   111  	for {
   112  		select {
   113  		case status := <-ch:
   114  			fmt.Printf(NotifMsgColor,
   115  				fmt.Sprintf("Value status change: %v", status.String()))
   116  		}
   117  	}
   118  }
   119  
   120  // listKnownModels prints information about every registered model - in the case
   121  // of this example, we have a model for interfaces, defined in ifplugin/model,
   122  // and models for BDs and FIBs, defined under l2plugin/model.
   123  func listKnownModels(c client.ConfigClient) {
   124  	knownModels, err := c.KnownModels("config")
   125  	if err != nil {
   126  		log.Fatalln(err)
   127  	}
   128  	fmt.Printf(DebugMsgColor,
   129  		fmt.Sprintf("Listing %d known models...", len(knownModels)))
   130  	for _, model := range knownModels {
   131  		fmt.Printf(DebugMsgColor, fmt.Sprintf(" - %v\n", model.String()))
   132  	}
   133  	time.Sleep(time.Second * 2)
   134  }
   135  
   136  func printMessage(lines ...string) {
   137  	border := strings.Repeat("~", 80)
   138  	fmt.Printf(InfoMsgColor, border)
   139  	for _, line := range lines {
   140  		fmt.Printf(InfoMsgColor, fmt.Sprintf("| %-76s |", line))
   141  	}
   142  	fmt.Printf(InfoMsgColor, border)
   143  	time.Sleep(time.Second * 2)
   144  }
   145  
   146  func informAboutGraphURL(txnNum int, afterResync bool, sleep bool) {
   147  	txnType := "data-update txn"
   148  	if afterResync {
   149  		txnType = "resync txn"
   150  	}
   151  	msg := fmt.Sprintf("Graph state after %s can be displayed at URL: %s?txn=%d\n",
   152  		txnType, graphURL, txnNum)
   153  	fmt.Printf(NoticeMsgColor, msg)
   154  	if sleep {
   155  		time.Sleep(time.Second * 5)
   156  	}
   157  }