diff --git a/plugins/ptp_operator/metrics/logparser.go b/plugins/ptp_operator/metrics/logparser.go index d5ed66e1..9e2043af 100644 --- a/plugins/ptp_operator/metrics/logparser.go +++ b/plugins/ptp_operator/metrics/logparser.go @@ -394,16 +394,32 @@ func (p *PTPEventManager) ParseGMLogs(processName, configName, output string, fi SyncState.With(map[string]string{"process": processName, "node": ptpNodeName, "iface": alias}).Set(GetSyncStateID(syncState)) // status metrics ptpStats[masterType].SetPtpDependentEventState(clockState, ptpStats.HasMetrics(processName), ptpStats.HasMetricHelp(processName)) - ptpStats[masterType].SetLastSyncState(clockState.State) ptpStats[masterType].SetAlias(alias) // If GM is locked/Freerun/Holdover then ptp state change event masterResource := fmt.Sprintf("%s/%s", alias, MasterClockType) + lastClockState := ptpStats[masterType].LastSyncState() - // When GM is enabled there is only event happening at GM level for now - p.GenPTPEvent(processName, ptpStats[masterType], masterResource, 0, clockState.State, ptp.PtpStateChange) - ptpStats[masterType].SetLastSyncState(clockState.State) - UpdateSyncStateMetrics(processName, alias, ptpStats[masterType].LastSyncState()) + // When GM is enabled, there is only one event happening at the GM level for now, so it is not being sent to the state decision routine. + // LOCKED -->FREERUN + //LOCKED->HOLDOVER + /// HOLDOVER-->FREERUN + // HOLDOVER-->LOCKED + + _, phaseOffset, _, err := ptpStats[types.IFace(iface)].GetDependsOnValueState(dpllProcessName, pointer.String(iface), phaseStatus) + if err != nil { + log.Errorf("error parsing phase offset %s", err.Error()) + } + ptpStats[masterType].SetLastOffset(int64(phaseOffset)) + lastOffset := ptpStats[masterType].LastOffset() + + if clockState.State != lastClockState { // publish directly here + log.Infof("%s sync state %s, last ptp state is : %s", masterResource, clockState.State, lastClockState) + p.PublishEvent(clockState.State, lastOffset, masterResource, ptp.PtpStateChange) + ptpStats[masterType].SetLastSyncState(clockState.State) + UpdateSyncStateMetrics(processName, alias, ptpStats[masterType].LastSyncState()) + UpdatePTPOffsetMetrics(processName, processName, alias, float64(lastOffset)) + } } // ParseDPLLLogs ... parse logs for various events diff --git a/plugins/ptp_operator/metrics/logparser_test.go b/plugins/ptp_operator/metrics/logparser_test.go index de0ac194..37672ac4 100644 --- a/plugins/ptp_operator/metrics/logparser_test.go +++ b/plugins/ptp_operator/metrics/logparser_test.go @@ -4,6 +4,7 @@ import ( "strings" "testing" + "github.com/redhat-cne/cloud-event-proxy/plugins/ptp_operator/event" "github.com/redhat-cne/cloud-event-proxy/plugins/ptp_operator/ptp4lconf" "github.com/redhat-cne/cloud-event-proxy/plugins/ptp_operator/metrics" @@ -145,3 +146,55 @@ func TestPTPEventManager_ParseDPLLLogs(t *testing.T) { assert.Equal(t, tt.expectedState, lastState) } } + +func Test_ParseGmLogs(t *testing.T) { + var ptpEventManager *metrics.PTPEventManager + tc := []testCase{ + { + processName: "GM", + output: "GM 1689014431 ts2phc.0.config ens2f1 T-GM-STATUS s0", + expectedState: ptp.FREERUN, + interfaceName: "ens2f1", + }, + { + processName: "GM", + output: "GM 1689014431 ts2phc.0.config ens2f1 T-GM-STATUS s1", + expectedState: ptp.HOLDOVER, + interfaceName: "ens2f1", + }, + { + processName: "GM", + output: "GM 1689014431 ts2phc.0.config ens2f1 T-GM-STATUS s2", + expectedState: ptp.LOCKED, + interfaceName: "ens2f1", + }, + } + ptpEventManager = metrics.NewPTPEventManager("", initPubSubTypes(), "tetsnode", nil) + ptpEventManager.MockTest(true) + ptpEventManager.Stats[types.ConfigName(ptp4lConfig.Name)] = make(stats.PTPStats) + ptpStats := ptpEventManager.GetStats(types.ConfigName(configName)) + replacer := strings.NewReplacer("[", " ", "]", " ", ":", " ") + for _, tt := range tc { + output := replacer.Replace(tt.output) + fields := strings.Fields(output) + ptpStats[types.IFace(tt.interfaceName)] = &stats.Stats{} + ptpStats[types.IFace(tt.interfaceName)].SetPtpDependentEventState( + event.ClockState{ + State: metrics.GetSyncState("s2"), + Offset: pointer.Float64(0), + IFace: &tt.interfaceName, + Process: "dpll", + ClockSource: event.DPLL, + Value: map[string]int64{"frequency_status": 2, "phase_status": int64(0), "pps_status": int64(2)}, + Metric: map[string]*event.PMetric{}, + NodeName: "tetsnode", + HelpText: map[string]string{"phase_status": "-1=UNKNOWN, 0=INVALID, 1=FREERUN, 2=LOCKED, 3=LOCKED_HO_ACQ, 4=HOLDOVER", "frequency_status": "-1=UNKNOWN, 0=INVALID, 1=FREERUN, 2=LOCKED, 3=LOCKED_HO_ACQ, 4=HOLDOVER", "pps_status": "0=UNAVAILABLE, 1=AVAILABLE"}, + }, ptpStats.HasMetrics("dpll"), ptpStats.HasMetricHelp("dpll")) + masterType := types.IFace(metrics.MasterClockType) + ptpStats[masterType] = &stats.Stats{} + ptpEventManager.ParseGMLogs(tt.processName, configName, output, fields, ptpStats) + lastState, errState := ptpStats[masterType].GetStateState(tt.processName, pointer.String(tt.interfaceName)) + assert.Equal(t, errState, nil) + assert.Equal(t, tt.expectedState, lastState) + } +} diff --git a/plugins/ptp_operator/metrics/metrics_test.go b/plugins/ptp_operator/metrics/metrics_test.go index 52058992..c0f528e1 100644 --- a/plugins/ptp_operator/metrics/metrics_test.go +++ b/plugins/ptp_operator/metrics/metrics_test.go @@ -280,6 +280,7 @@ var testCases = []TestCase{ expectedNmeaStatus: SKIP, expectedPpsStatus: SKIP, expectedClockClassMetrics: SKIP, + expectedEvent: ptp.PtpStateChange, }, { log: "gnss[1000000500]:[ts2phc.0.config] ens2f1 gnss_status 3 offset 5 s2",