1 /*
2  * Copyright (C) 2012 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5  * use this file except in compliance with the License. You may obtain a copy of
6  * the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13  * License for the specific language governing permissions and limitations under
14  * the License.
15  */
16 
17 #include <sys/stat.h>
18 #include <sys/types.h>
19 #include <errno.h>
20 
21 #include <memory>
22 
23 #include "Log.h"
24 #include "FileUtil.h"
25 #include "Report.h"
26 #include "StringUtil.h"
27 #include "task/TaskCase.h"
28 #include "task/TaskGeneric.h"
29 #include "task/TaskSave.h"
30 
31 static const android::String8 STR_FILE("file");
32 static const android::String8 STR_REPORT("report");
33 
TaskSave()34 TaskSave::TaskSave()
35     : TaskGeneric(TaskGeneric::ETaskSave)
36 {
37     const android::String8* list[] = {&STR_FILE, &STR_REPORT, NULL};
38     registerSupportedStringAttributes(list);
39 }
40 
~TaskSave()41 TaskSave::~TaskSave()
42 {
43 
44 }
45 
handleFile()46 bool TaskSave::handleFile()
47 {
48     android::String8 fileValue;
49     if (!findStringAttribute(STR_FILE, fileValue)) {
50         LOGI("no saving to file");
51         return true; // true as there is no need to save
52     }
53 
54     std::unique_ptr<std::vector<android::String8> > list(StringUtil::split(fileValue, ','));
55     std::vector<android::String8>* listp = list.get();
56     if (listp == NULL) {
57         LOGE("alloc failed");
58         return false;
59     }
60 
61     android::String8 dirName;
62     if (!FileUtil::prepare(dirName)) {
63         LOGE("cannot prepare report dir");
64         return false;
65     }
66     android::String8 caseName;
67     if (!getTestCase()->getCaseName(caseName)) {
68         return false;
69     }
70     dirName.appendPath(caseName);
71     int result = mkdir(dirName.string(), S_IRWXU);
72     if ((result == -1) && (errno != EEXIST)) {
73         LOGE("mkdir of save dir %s failed, error %d", dirName.string(), errno);
74         return false;
75     }
76 
77     for (size_t i = 0; i < listp->size(); i++) {
78         std::unique_ptr<std::list<TaskCase::BufferPair> > buffers(
79                 getTestCase()->findAllBuffers((*listp)[i]));
80         std::list<TaskCase::BufferPair>* buffersp = buffers.get();
81         if (buffersp == NULL) {
82             LOGE("no buffer for given pattern %s", ((*listp)[i]).string());
83             return false;
84         }
85         std::list<TaskCase::BufferPair>::iterator it = buffersp->begin();
86         std::list<TaskCase::BufferPair>::iterator end = buffersp->end();
87         for (; it != end; it++) {
88             android::String8 fileName(dirName);
89             fileName.appendPath(it->first);
90             if (!it->second->saveToFile(fileName)) {
91                 LOGE("save failed");
92                 return false;
93             }
94         }
95     }
96     return true;
97 }
98 
handleReport()99 bool TaskSave::handleReport()
100 {
101     android::String8 reportValue;
102     if (!findStringAttribute(STR_REPORT, reportValue)) {
103         LOGI("no saving to report");
104         return true; // true as there is no need to save
105     }
106 
107     std::unique_ptr<std::vector<android::String8> > list(StringUtil::split(reportValue, ','));
108     std::vector<android::String8>* listp = list.get();
109     if (listp == NULL) {
110         LOGE("alloc failed");
111         return false;
112     }
113     MSG("=== Values stored ===");
114     android::String8 details;
115     for (size_t i = 0; i < listp->size(); i++) {
116         std::unique_ptr<std::list<TaskCase::ValuePair> > values(
117                 getTestCase()->findAllValues((*listp)[i]));
118         std::list<TaskCase::ValuePair>* valuesp = values.get();
119         if (valuesp == NULL) {
120             LOGE("no value for given pattern %s", ((*listp)[i]).string());
121             return false;
122         }
123         std::list<TaskCase::ValuePair>::iterator it = values->begin();
124         std::list<TaskCase::ValuePair>::iterator end = values->end();
125 
126         for (; it != end; it++) {
127             if (it->second.getType() == TaskCase::Value::ETypeDouble) {
128                 details.appendFormat("   %s: %f\n", it->first.string(), it->second.getDouble());
129             } else { //64bit int
130                 details.appendFormat("   %s: %lld\n", it->first.string(), it->second.getInt64());
131             }
132         }
133         MSG("%s", details.string());
134     }
135     getTestCase()->setDetails(details);
136     return true;
137 }
138 
run()139 TaskGeneric::ExecutionResult TaskSave::run()
140 {
141     bool failed = false;
142     if (!handleFile()) {
143         failed = true;
144     }
145     if (!handleReport()) {
146         failed = true;
147     }
148     if (failed) {
149         return TaskGeneric::EResultError;
150     } else {
151         return TaskGeneric::EResultOK;
152     }
153 }
154 
155 
156