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 <inttypes.h>
18 #include <sys/stat.h>
19 #include <sys/types.h>
20 #include <errno.h>
21 
22 #include <memory>
23 
24 #include "Log.h"
25 #include "FileUtil.h"
26 #include "Report.h"
27 #include "StringUtil.h"
28 #include "task/TaskCase.h"
29 #include "task/TaskGeneric.h"
30 #include "task/TaskSave.h"
31 
32 static const android::String8 STR_FILE("file");
33 static const android::String8 STR_REPORT("report");
34 
TaskSave()35 TaskSave::TaskSave()
36     : TaskGeneric(TaskGeneric::ETaskSave)
37 {
38     const android::String8* list[] = {&STR_FILE, &STR_REPORT, NULL};
39     registerSupportedStringAttributes(list);
40 }
41 
~TaskSave()42 TaskSave::~TaskSave()
43 {
44 
45 }
46 
handleFile()47 bool TaskSave::handleFile()
48 {
49     android::String8 fileValue;
50     if (!findStringAttribute(STR_FILE, fileValue)) {
51         LOGI("no saving to file");
52         return true; // true as there is no need to save
53     }
54 
55     std::unique_ptr<std::vector<android::String8> > list(StringUtil::split(fileValue, ','));
56     std::vector<android::String8>* listp = list.get();
57     if (listp == NULL) {
58         LOGE("alloc failed");
59         return false;
60     }
61 
62     android::String8 dirName;
63     if (!FileUtil::prepare(dirName)) {
64         LOGE("cannot prepare report dir");
65         return false;
66     }
67     android::String8 caseName;
68     if (!getTestCase()->getCaseName(caseName)) {
69         return false;
70     }
71     dirName.appendPath(caseName);
72     int result = mkdir(dirName.string(), S_IRWXU);
73     if ((result == -1) && (errno != EEXIST)) {
74         LOGE("mkdir of save dir %s failed, error %d", dirName.string(), errno);
75         return false;
76     }
77 
78     for (size_t i = 0; i < listp->size(); i++) {
79         std::unique_ptr<std::list<TaskCase::BufferPair> > buffers(
80                 getTestCase()->findAllBuffers((*listp)[i]));
81         std::list<TaskCase::BufferPair>* buffersp = buffers.get();
82         if (buffersp == NULL) {
83             LOGE("no buffer for given pattern %s", ((*listp)[i]).string());
84             return false;
85         }
86         std::list<TaskCase::BufferPair>::iterator it = buffersp->begin();
87         std::list<TaskCase::BufferPair>::iterator end = buffersp->end();
88         for (; it != end; it++) {
89             android::String8 fileName(dirName);
90             fileName.appendPath(it->first);
91             if (!it->second->saveToFile(fileName)) {
92                 LOGE("save failed");
93                 return false;
94             }
95         }
96     }
97     return true;
98 }
99 
handleReport()100 bool TaskSave::handleReport()
101 {
102     android::String8 reportValue;
103     if (!findStringAttribute(STR_REPORT, reportValue)) {
104         LOGI("no saving to report");
105         return true; // true as there is no need to save
106     }
107 
108     std::unique_ptr<std::vector<android::String8> > list(StringUtil::split(reportValue, ','));
109     std::vector<android::String8>* listp = list.get();
110     if (listp == NULL) {
111         LOGE("alloc failed");
112         return false;
113     }
114     MSG("=== Values stored ===");
115     android::String8 details;
116     for (size_t i = 0; i < listp->size(); i++) {
117         std::unique_ptr<std::list<TaskCase::ValuePair> > values(
118                 getTestCase()->findAllValues((*listp)[i]));
119         std::list<TaskCase::ValuePair>* valuesp = values.get();
120         if (valuesp == NULL) {
121             LOGE("no value for given pattern %s", ((*listp)[i]).string());
122             return false;
123         }
124         std::list<TaskCase::ValuePair>::iterator it = values->begin();
125         std::list<TaskCase::ValuePair>::iterator end = values->end();
126 
127         for (; it != end; it++) {
128             if (it->second.getType() == TaskCase::Value::ETypeDouble) {
129                 details.appendFormat("   %s: %f\n", it->first.string(), it->second.getDouble());
130             } else { //64bit int
131                 details.appendFormat("   %s: %" PRId64 "\n", it->first.string(),
132                                      it->second.getInt64());
133             }
134         }
135         MSG("%s", details.string());
136     }
137     getTestCase()->setDetails(details);
138     return true;
139 }
140 
run()141 TaskGeneric::ExecutionResult TaskSave::run()
142 {
143     bool failed = false;
144     if (!handleFile()) {
145         failed = true;
146     }
147     if (!handleReport()) {
148         failed = true;
149     }
150     if (failed) {
151         return TaskGeneric::EResultError;
152     } else {
153         return TaskGeneric::EResultOK;
154     }
155 }
156 
157 
158