diff --git a/applications/rtdt-manager/benchmark/benchmark.go b/applications/rtdt-manager/benchmark/benchmark.go index d3e224f9ebfaf35e91a434112b99355af983b40a..1adbf17160b4dbbd7cceef79fcecfa93e4d07df6 100644 --- a/applications/rtdt-manager/benchmark/benchmark.go +++ b/applications/rtdt-manager/benchmark/benchmark.go @@ -1,23 +1,25 @@ package benchmark import ( + "encoding/json" "fmt" + "os" "time" ) type Benchmark0 struct { - StartTimeRealnet time.Time - - SendChangeRequest time.Time - ReceiveChangeRequest time.Time - ReceiveChangeResponse time.Time - ChangeRequestEnd time.Time - - SendCommitRequest time.Time - ReceiveCommitResponse time.Time - CommitEnd time.Time - EndTime time.Time - PropagationDelay time.Duration + StartTimeRealnet time.Time // Callback entered + + SendChangeRequest time.Time // realnet sends change request + ReceiveChangeRequest time.Time // the change reuest received in twin + ReceiveChangeResponse time.Time // the change request is received in twin + + SendCommitRequest time.Time // the commit is sent from realnet + ReceiveCommitRequest time.Time // the commit is received in twin + ReceiveCommitResponse time.Time // the response of the twin received in realnet + //EndTime time.Time + + PropagationDelay time.Duration // calculated delay } var Current Benchmark0 @@ -33,8 +35,46 @@ func Diff(start, end time.Time) time.Duration { } func (b *Benchmark0) Print() { - fmt.Println("StartTimeRealnet:") - fmt.Println("SendChangeRequest to ReceiveChangeRequest:", b.ReceiveChangeRequest.Sub(b.SendChangeRequest).Microseconds()) - fmt.Println("SendChangeRequest to ChangeRequestEnd:", b.ChangeRequestEnd.Sub(b.SendChangeRequest).Microseconds()) - fmt.Println("PropagationDelay:", b.PropagationDelay.Microseconds()) + fmt.Println("SendChangeRequest to ReceiveChangeRequest in us:", b.ReceiveChangeRequest.Sub(b.SendChangeRequest).Microseconds()) + fmt.Println("SendChangeRequest to ReceiveChangeResponse in us:", b.ReceiveChangeResponse.Sub(b.SendChangeRequest).Microseconds()) + fmt.Println("PropagationDelay in ms:", b.PropagationDelay.Milliseconds()) +} + +func AppendToJsonFile(fname string, b *Benchmark0) { + var benchmarks []Benchmark0 + + // Check if file exists + if _, err := os.Stat(fname); err == nil { + // File exists, read existing content + data, err := os.ReadFile(fname) + if err != nil { + fmt.Println("Error reading file:", err) + return + } + if len(data) > 0 { + err = json.Unmarshal(data, &benchmarks) + if err != nil { + fmt.Println("Error unmarshaling JSON:", err) + return + } + } + } else if !os.IsNotExist(err) { + fmt.Println("Error checking file status:", err) + return + } + + // Append the new benchmark + benchmarks = append(benchmarks, *b) + + // Marshal and write back to file + outData, err := json.MarshalIndent(benchmarks, "", " ") + if err != nil { + fmt.Println("Error marshaling JSON:", err) + return + } + + err = os.WriteFile(fname, outData, 0644) + if err != nil { + fmt.Println("Error writing to file:", err) + } } diff --git a/applications/rtdt-manager/rtdt-manager/rtdt-manager.go b/applications/rtdt-manager/rtdt-manager/rtdt-manager.go index c237a8186719e09fa911b118ed04c5d3cb105db6..807f2341080b4b815f417b25312506618691261b 100644 --- a/applications/rtdt-manager/rtdt-manager/rtdt-manager.go +++ b/applications/rtdt-manager/rtdt-manager/rtdt-manager.go @@ -87,6 +87,7 @@ func (r *RtdtManager) LaunchRealnetVEnv(realnetName string, sdnConfig *sdnconfig if r.realnet == nil { return fmt.Errorf("Error in LaunchRealnet: Couldn't deploy VEnv") } + r.realnet.SyncBack = true err = r.realnet.ApplyConfiguration(sdnConfig) if err != nil { fmt.Printf("Failed to apply configuration: %v\n", err) @@ -256,7 +257,8 @@ func (r *RtdtManager) RunBenchmark0(numTests int64) error { } //results := make([]time.Duration, numTests) // Change a property and measure the time when it's applied - for i, value := 0, int64(2001); i < int(numTests); i, value = i+1, value+1 { + //for i, value := 0, int64(2001); i < int(numTests); i, value = i+1, value+1 { + for i := int64(0); i < numTests; i++ { randBytes := make([]byte, 4) _, err := rand.Read(randBytes) if err != nil { @@ -271,10 +273,7 @@ func (r *RtdtManager) RunBenchmark0(numTests int64) error { } } - - // for i, res := range results { - // fmt.Printf("%d - %v\n", i, res) - // } + r.benchmark0 = false return nil } @@ -317,9 +316,10 @@ func (r *RtdtManager) Run() error { }() go func() { scanner := bufio.NewScanner(os.Stdin) + fmt.Println("Welcome to rtdt-manager, please type h/help to show available commands") for { - fmt.Print("$cmd (type 'h' to show commands):") + fmt.Print("[rtdt-manager] > ") if !scanner.Scan() { fmt.Println("Failed to read from stdin. Exiting!") close(r.stopChan) @@ -365,7 +365,7 @@ func (r *RtdtManager) Run() error { var err error if len(tokens) == 2 { numTests, err = strconv.ParseInt(tokens[1], 10, 64) - if err != nil { + if err == nil { r.RunBenchmark0(numTests) } else { fmt.Printf("Couldn't parse second argument as int64\n") @@ -455,6 +455,9 @@ func (r *RtdtManager) InitEventSystem() error { }) eventServMneTwin.SetupEventReciever(make(chan os.Signal, 1)) twin.EventSystemStarted = true + // only turn it on now so that the first few events are discarded + // These are events that pertain data that should be concsiously misaligned + twin.SyncBack = true } } @@ -462,7 +465,9 @@ func (r *RtdtManager) InitEventSystem() error { } func (r *RtdtManager) updateMNECallbackTwin(event *event.Event) { - // Don't save changes we receive from realnet + // Called when receiving changes in twin + // realnet will write false to venv.SyncBack in its callback + // So don't save changes we receive from realnet callback: if !r.rtdt_twins[0].SyncBack { return } @@ -484,9 +489,9 @@ func (r *RtdtManager) updateMNECallbackRealnet(event *event.Event) { if !r.realnet.SyncBack { return } - var b0 benchmark.Benchmark0 if r.benchmark0 { - b0.StartTimeRealnet = time.Now() + benchmark.Current = benchmark.Benchmark0{} + benchmark.Current.StartTimeRealnet = time.Now() } fmt.Println("--------------------------------") fmt.Println("---------- MNE EVENT -----------") diff --git a/applications/rtdt-manager/sdnconfig/sdnconfig.go b/applications/rtdt-manager/sdnconfig/sdnconfig.go index d9845b326f6409cca3ccf87893aa4c0b5285bdb5..60462982688ae7440682a093100dcbdad9c60f6a 100644 --- a/applications/rtdt-manager/sdnconfig/sdnconfig.go +++ b/applications/rtdt-manager/sdnconfig/sdnconfig.go @@ -33,16 +33,16 @@ type Metadata struct { } type NetworkElement struct { - ID string `json:"id"` - Name string `json:"name"` - TransportType string `json:"transport_type"` - TransportAddress string `json:"transport_address"` - TransportUsername string `json:"transport_username"` - TransportPassword string `json:"transport_password"` - TransportTLS bool `json:"transport_tls"` - Plugin string `json:"plugin"` - Model string `json:"model"` - PndID string `json:"pnd_id"` + ID string `json:"id"` + Name string `json:"name"` + TransportType string `json:"transport_type"` + TransportAddress string `json:"transport_address"` + TransportUsername string `json:"transport_username"` + TransportPassword string `json:"transport_password"` + TransportTLS bool `json:"transport_tls"` + Plugin string `json:"plugin"` + Model string `json:"model"` + PndID string `json:"pnd_id"` GnmiSubscriptionPaths [][]string `json:"gnmi_transcription_paths,omitempty" bson:"gnmi_transcription_paths,omitempty"` } @@ -123,15 +123,6 @@ func (s *SdnConfig) LoadSdnConfig(configFilename string) error { if err != nil { return fmt.Errorf("Error in LoadSdnConfig(): %w", err) } - - // Output - // jsonData, err := json.MarshalIndent(s, "", " ") - // if err != nil { - // return fmt.Errorf("Error marshalling struct to JSON: %w", err) - // } - // fmt.Println("------- SDNCONFIG ------------") - // fmt.Println(string(jsonData)) - // fmt.Println("------- SDNCONFIG ------------") return nil } @@ -157,7 +148,7 @@ func (s *SdnConfig) WriteSdnConfig(configFilename string) error { // Limitations: // - No differing prefix lengths between realnet, twin, // - No prefix lengths other than 8, 16, 24 (cidr) -// For now: Also delete plugins and set mne plugins statically +// For now: Also delete plugins and set mne plugins statically, because this is bugged in the controller func (s *SdnConfig) Transpose(name, addressIpv4, addressIpv6 string, ipv4PrefixLength int) { ipv4Parts := strings.Split(addressIpv4, ".") for i := range s.Nodes { @@ -198,19 +189,9 @@ func (s *SdnConfig) transposeModel(model, ipv4, oldIpv4 string, ipv4PrefixLength OldIpv4Parts := strings.Split(oldIpv4, ".") networkPortionLength := ipv4PrefixLength / 8 oldNetworkPortion := strings.Join(OldIpv4Parts[:networkPortionLength], ".") - fmt.Println("transposeModel(): oldNetworkPortion =", oldNetworkPortion) newNetworkPortion := strings.Join(ipv4Parts[:networkPortionLength], ".") - fmt.Println("transposeModel(): newNetworkPortion =", newNetworkPortion) model = strings.ReplaceAll(model, oldNetworkPortion, newNetworkPortion) - // Hacky ipv6 replacement, doesn't work yet.. - // ipv6Regex := regexp.MustCompile(`([0-9a-fA-F:]+:+[0-9a-fA-F]*)`) - // model = ipv6Regex.ReplaceAllString(model, ipv6) - - fmt.Println("---------------- NEW MODEL --------------------") - fmt.Println(model) - fmt.Println("---------------- NEW MODEL --------------------") - return model } diff --git a/applications/rtdt-manager/venv/venv.go b/applications/rtdt-manager/venv/venv.go index 8d300079c5a4dee570490e7a409ec042deb8ba31..e035991588b6d4f32d07bf876cdc88326a434454 100644 --- a/applications/rtdt-manager/venv/venv.go +++ b/applications/rtdt-manager/venv/venv.go @@ -4,6 +4,7 @@ import ( "context" "encoding/json" "fmt" + "path/filepath" "strconv" "strings" "sync" @@ -122,7 +123,7 @@ func NewVEnv(name, clabFilename, user, pass string, wg *sync.WaitGroup, sdnConfi waitGroup: wg, sdnConfig: sdnConfig, containerRegistryURL: "registry.code.fbi.h-da.de/danet/gnmi-target/debian:interface-enabled-test", // TODO: Could let user choose - SyncBack: true, + SyncBack: false, } } @@ -327,7 +328,7 @@ func (v *VEnv) SetGnmiPath(path, value, mneid string, save bool) error { if err != nil { fmt.Println("The given type is not supported yet!") } - fmt.Println("gnmiVal:", gnmiVal) + fmt.Println("gnmiVal:", gnmiVal) changeRequest := &networkelement.ChangeRequest{ Mneid: mneid, @@ -349,7 +350,7 @@ func (v *VEnv) SetGnmiPath(path, value, mneid string, save bool) error { } setPathResponse, err := mneService.SetPathList(ctx, setPathListReq) if save { - benchmark.Current.ChangeRequestEnd = time.Now() + benchmark.Current.ReceiveChangeResponse = time.Now() // TOA of response } if err != nil { fmt.Printf("Error: %v\n", err) @@ -370,16 +371,13 @@ func (v *VEnv) SetGnmiPath(path, value, mneid string, save bool) error { } clResponse, err := mneService.SetChangeList(ctx, &setChangeListRequest) if save { - benchmark.Current.CommitEnd = time.Now() + benchmark.Current.ReceiveCommitResponse = time.Now() } if err != nil { fmt.Println("Error, failed to commit changes:", err) return err } else { fmt.Println("Successfully applied changes:", clResponse) - if save { - benchmark.Current.CommitEnd = time.Now() - } } if save { @@ -389,10 +387,17 @@ func (v *VEnv) SetGnmiPath(path, value, mneid string, save bool) error { benchmark.Current.SendCommitRequest = time.Unix(0, setChangeListRequest.Timestamp) benchmark.Current.ReceiveCommitResponse = time.Unix(0, clResponse.Timestamp) - benchmark.Current.PropagationDelay = benchmark.Current.StartTimeRealnet.Sub(benchmark.Current.EndTime) + benchmark.Current.PropagationDelay = benchmark.Current.ReceiveCommitResponse.Sub(benchmark.Current.StartTimeRealnet) fmt.Println("---Measurement finished---") benchmark.Current.Print() + gosdnutil.ConfigTmpPath() + confPath, err := gosdnutil.ConfigTmpPath() + if err != nil { + return fmt.Errorf("Couldn't get gosdn path: %w", err) + } + filename := filepath.Join(confPath, "measure.json") + benchmark.AppendToJsonFile(filename, &benchmark.Current) } return nil }