• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 xdevice
17
18import (
19	"context"
20	"crypto/md5"
21	"encoding/xml"
22	"errors"
23	"fmt"
24	"fotff/tester"
25	"fotff/utils"
26	"github.com/sirupsen/logrus"
27	"math/rand"
28	"os"
29	"path/filepath"
30	"strings"
31	"time"
32)
33
34const enableTestModeScript = `mount -o rw,remount /; param set persist.ace.testmode.enabled 1; param set persist.sys.hilog.debug.on true; sed -i 's/enforcing/permissive/g' /system/etc/selinux/config; sync; reboot`
35
36type Tester struct {
37	Task          string `key:"task" default:"acts"`
38	Config        string `key:"config" default:"./config/user_config.xml"`
39	TestCasesPath string `key:"test_cases_path" default:"./testcases"`
40	ResourcePath  string `key:"resource_path" default:"./resource"`
41}
42
43type Report struct {
44	XMLName   xml.Name `xml:"testsuites"`
45	TestSuite []struct {
46		TestCase []struct {
47			Name   string `xml:"name,attr"`
48			Result string `xml:"result,attr"`
49		} `xml:"testcase"`
50	} `xml:"testsuite"`
51}
52
53func init() {
54	rand.Seed(time.Now().UnixNano())
55}
56
57func NewTester() tester.Tester {
58	ret := &Tester{}
59	utils.ParseFromConfigFile("xdevice", ret)
60	return ret
61}
62
63func (t *Tester) TaskName() string {
64	return t.Task
65}
66
67func (t *Tester) Prepare(pkgDir string, device string, ctx context.Context) (err error) {
68	logrus.Info("for xdevice test, try to enable test mode...")
69	if err := utils.HdcShell(enableTestModeScript, device, ctx); err != nil {
70		return err
71	}
72	time.Sleep(20 * time.Second) // usually, it takes about 20s to reboot into OpenHarmony
73	if connected := utils.WaitHDC(device, ctx); !connected {
74		logrus.Errorf("enable test mode at device %s done, but boot unnormally, hdc connection fail", device)
75		return fmt.Errorf("enable test mode at device %s done, but boot unnormally, hdc connection fail", device)
76	}
77	time.Sleep(10 * time.Second) // wait 10s more to ensure system has been started completely
78	logrus.Infof("enable test mode at device %s successfully", device)
79	return nil
80}
81
82func (t *Tester) DoTestTask(deviceSN string, ctx context.Context) (ret []tester.Result, err error) {
83	reportDir := fmt.Sprintf("%X", md5.Sum([]byte(fmt.Sprintf("%d", rand.Int()))))
84	args := []string{"-m", "xdevice", "run", t.Task, "-c", t.Config, "-tcpath", t.TestCasesPath, "-respath", t.ResourcePath, "-rp", reportDir}
85	if deviceSN != "" {
86		args = append(args, "-sn", deviceSN)
87	}
88	if err := utils.ExecContext(ctx, "python", args...); err != nil {
89		if errors.Is(err, context.Canceled) {
90			return nil, err
91		}
92		logrus.Errorf("do test suite fail: %v", err)
93		return nil, err
94	}
95	return t.readReport(reportDir)
96}
97
98func (t *Tester) DoTestCase(deviceSN, testCase string, ctx context.Context) (ret tester.Result, err error) {
99	reportDir := fmt.Sprintf("%X", md5.Sum([]byte(fmt.Sprintf("%d", rand.Int()))))
100	args := []string{"-m", "xdevice", "run", "-l", testCase, "-c", t.Config, "-tcpath", t.TestCasesPath, "-respath", t.ResourcePath, "-rp", reportDir}
101	if deviceSN != "" {
102		args = append(args, "-sn", deviceSN)
103	}
104	if err := utils.ExecContext(ctx, "python", args...); err != nil {
105		if errors.Is(err, context.Canceled) {
106			return ret, err
107		}
108		logrus.Errorf("do test case %s fail: %v", testCase, err)
109		return ret, err
110	}
111	r, err := t.readReport(reportDir)
112	if len(r) == 0 {
113		return ret, fmt.Errorf("read latest report err, no result found")
114	}
115	if r[0].TestCaseName != testCase {
116		return ret, fmt.Errorf("read latest report err, no matched result found")
117	}
118	logrus.Infof("do testcase %s at %s done, result is %s", r[0].TestCaseName, deviceSN, r[0].Status)
119	return r[0], nil
120}
121
122func (t *Tester) DoTestCases(deviceSN string, testcases []string, ctx context.Context) (ret []tester.Result, err error) {
123	reportDir := fmt.Sprintf("%X", md5.Sum([]byte(fmt.Sprintf("%d", rand.Int()))))
124	args := []string{"-m", "xdevice", "run", "-l", strings.Join(testcases, ";"), "-c", t.Config, "-tcpath", t.TestCasesPath, "-respath", t.ResourcePath, "-rp", reportDir}
125	if deviceSN != "" {
126		args = append(args, "-sn", deviceSN)
127	}
128	if err := utils.ExecContext(ctx, "python", args...); err != nil {
129		if errors.Is(err, context.Canceled) {
130			return ret, err
131		}
132		logrus.Errorf("do test cases %v fail: %v", testcases, err)
133		return ret, err
134	}
135	return t.readReport(reportDir)
136}
137
138func (t *Tester) readReport(reportDir string) (ret []tester.Result, err error) {
139	data, err := os.ReadFile(filepath.Join("reports", reportDir, "summary_report.xml"))
140	if err != nil {
141		logrus.Errorf("read report xml fail: %v", err)
142		return nil, err
143	}
144	var report Report
145	err = xml.Unmarshal(data, &report)
146	if err != nil {
147		logrus.Errorf("unmarshal report xml fail: %v", err)
148		return nil, err
149	}
150	for _, s := range report.TestSuite {
151		for _, c := range s.TestCase {
152			var status tester.ResultStatus
153			if c.Result == "true" {
154				status = tester.ResultPass
155			} else {
156				status = tester.ResultFail
157			}
158			ret = append(ret, tester.Result{TestCaseName: c.Name, Status: status})
159		}
160	}
161	return ret, err
162}
163