1/*
2 * Copyright (c) 2022 Huawei Device Co., Ltd.
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
16package rec
17
18import (
19	"context"
20	"encoding/json"
21	"fotff/pkg"
22	"fotff/tester"
23	"fotff/utils"
24	"github.com/sirupsen/logrus"
25	"time"
26)
27
28var Records = make(map[string]Record)
29
30func init() {
31	data, err := utils.ReadRuntimeData("records.json")
32	if err != nil {
33		return
34	}
35	if err := json.Unmarshal(data, &Records); err != nil {
36		logrus.Errorf("unmarshal records err: %v", err)
37	}
38}
39
40func Save() {
41	data, err := json.MarshalIndent(Records, "", "\t")
42	if err != nil {
43		logrus.Errorf("marshal records err: %v", err)
44		return
45	}
46	if err := utils.WriteRuntimeData("records.json", data); err != nil {
47		logrus.Errorf("save records err: %v", err)
48		return
49	}
50	logrus.Infof("save records successfully")
51}
52
53func HandleResults(t tester.Tester, dev string, pkgName string, results []tester.Result) []string {
54	var passes, fails []tester.Result
55	for _, result := range results {
56		switch result.Status {
57		case tester.ResultPass:
58			passes = append(passes, result)
59		case tester.ResultFail:
60			fails = append(fails, result)
61		}
62	}
63	handlePassResults(pkgName, passes)
64	return handleFailResults(t, dev, pkgName, fails)
65}
66
67func handlePassResults(pkgName string, results []tester.Result) {
68	for _, result := range results {
69		logrus.Infof("recording [%s] as a success, the lastest success package is [%s]", result.TestCaseName, pkgName)
70		Records[result.TestCaseName] = Record{
71			UpdateTime:       time.Now().Format("2006-01-02 15:04:05"),
72			Status:           tester.ResultPass,
73			LatestSuccessPkg: pkgName,
74			EarliestFailPkg:  "",
75			FailIssueURL:     "",
76		}
77	}
78}
79
80func handleFailResults(t tester.Tester, dev string, pkgName string, results []tester.Result) []string {
81	var fotffTestCases []string
82	for _, result := range results {
83		if record, ok := Records[result.TestCaseName]; ok && record.Status != tester.ResultPass {
84			logrus.Warnf("test case %s had failed before, skip handle it", result.TestCaseName)
85			continue
86		}
87		status := tester.ResultFail
88		for i := 0; i < 3; i++ {
89			r, err := t.DoTestCase(dev, result.TestCaseName, context.TODO())
90			if err != nil {
91				logrus.Errorf("failed to do test case %s: %v", result.TestCaseName, err)
92				continue
93			}
94			logrus.Infof("do testcase %s at %s done, result is %s", r.TestCaseName, dev, r.Status)
95			if r.Status == tester.ResultPass {
96				logrus.Warnf("testcase %s result is %s", r.TestCaseName, tester.ResultOccasionalFail)
97				status = tester.ResultOccasionalFail
98				break
99			}
100		}
101		if status == tester.ResultFail && Records[result.TestCaseName].LatestSuccessPkg != "" && Records[result.TestCaseName].EarliestFailPkg == "" {
102			fotffTestCases = append(fotffTestCases, result.TestCaseName)
103		}
104		Records[result.TestCaseName] = Record{
105			UpdateTime:       time.Now().Format("2006-01-02 15:04:05"),
106			Status:           status,
107			LatestSuccessPkg: Records[result.TestCaseName].LatestSuccessPkg,
108			EarliestFailPkg:  pkgName,
109			FailIssueURL:     "",
110		}
111	}
112	return fotffTestCases
113}
114
115func Analysis(m pkg.Manager, t tester.Tester, pkgName string, testcases []string) {
116	for i, testcase := range testcases {
117		record := Records[testcase]
118		logrus.Infof("%s failed, the lastest success package is [%s], earliest fail package is [%s], now finding out the first fail...", testcase, record.LatestSuccessPkg, pkgName)
119		issueURL, err := FindOutTheFirstFail(m, t, testcase, record.LatestSuccessPkg, pkgName, testcases[i+1:]...)
120		if err != nil {
121			logrus.Errorf("failed to find out the first fail issue, err: %v", err)
122			issueURL = err.Error()
123		}
124		logrus.Infof("recording %s as a failure, the lastest success package is [%s], the earliest fail package is [%s], fail issue URL is [%s]", testcase, record.LatestSuccessPkg, pkgName, issueURL)
125		Records[testcase] = Record{
126			UpdateTime:       time.Now().Format("2006-01-02 15:04:05"),
127			Status:           tester.ResultFail,
128			LatestSuccessPkg: record.LatestSuccessPkg,
129			EarliestFailPkg:  pkgName,
130			FailIssueURL:     issueURL,
131		}
132	}
133}
134