1 /* Copyright 2011 JetBrains s.r.o.
2 *
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 * $Revision: 88625 $
16 */
17
18 #include "tests/gtest/teamcity/src/teamcity_messages.h"
19
20 #include <cstdlib>
21 #include <sstream>
22
23 namespace jetbrains {
24 namespace teamcity {
25
getFlowIdFromEnvironment()26 std::string getFlowIdFromEnvironment() {
27 #if (defined(WIN32) || defined(_WIN32) || defined(__WIN32)) && !defined(__CYGWIN__) && !defined(__MINGW32__)
28 char *flowId = NULL;
29 size_t sz = 0;
30 std::string result;
31 if(!_dupenv_s(&flowId, &sz,"TEAMCITY_PROCESS_FLOW_ID")) {
32 result = flowId != NULL ? flowId : "";
33 free(flowId);
34 }
35
36 return result;
37 #else
38 const char *flowId = getenv("TEAMCITY_PROCESS_FLOW_ID");
39 return flowId == NULL ? "" : flowId;
40 #endif
41 }
42
underTeamcity()43 bool underTeamcity() {
44 #if (defined(WIN32) || defined(_WIN32) || defined(__WIN32)) && !defined(__CYGWIN__) && !defined(__MINGW32__)
45 char *teamCityProjectName = 0;
46 size_t sz = 0;
47 bool result = false;
48 if(!_dupenv_s(&teamCityProjectName, &sz, "TEAMCITY_PROJECT_NAME")) {
49 result = teamCityProjectName != NULL;
50 free(teamCityProjectName);
51 }
52
53 return result;
54 #else
55 return getenv("TEAMCITY_PROJECT_NAME") != NULL;
56 #endif
57 }
58
TeamcityMessages()59 TeamcityMessages::TeamcityMessages()
60 : m_out(&std::cout)
61 {}
62
setOutput(std::ostream & out)63 void TeamcityMessages::setOutput(std::ostream &out) {
64 m_out = &out;
65 }
66
escape(const std::string & s)67 std::string TeamcityMessages::escape(const std::string &s) {
68 std::string result;
69 result.reserve(s.length());
70
71 for (size_t i = 0; i < s.length(); i++) {
72 char c = s[i];
73
74 switch (c) {
75 case '\n': result.append("|n"); break;
76 case '\r': result.append("|r"); break;
77 case '\'': result.append("|'"); break;
78 case '|': result.append("||"); break;
79 case ']': result.append("|]"); break;
80 default: result.append(&c, 1);
81 }
82 }
83
84 return result;
85 }
86
openMsg(const std::string & name)87 void TeamcityMessages::openMsg(const std::string &name) {
88 // endl for http://jetbrains.net/tracker/issue/TW-4412
89 *m_out << std::endl << "##teamcity[" << name;
90 }
91
closeMsg()92 void TeamcityMessages::closeMsg() {
93 *m_out << "]";
94 // endl for http://jetbrains.net/tracker/issue/TW-4412
95 *m_out << std::endl;
96 }
97
writeProperty(const std::string & name,const std::string & value)98 void TeamcityMessages::writeProperty(const std::string &name, const std::string &value) {
99 *m_out << " " << name << "='" << escape(value) << "'";
100 }
101
suiteStarted(const std::string & name,const std::string & flowid)102 void TeamcityMessages::suiteStarted(const std::string &name, const std::string &flowid) {
103 openMsg("testSuiteStarted");
104 writeProperty("name", name);
105 if(flowid.length() > 0) {
106 writeProperty("flowId", flowid);
107 }
108
109 closeMsg();
110 }
111
suiteFinished(const std::string & name,const std::string & flowid)112 void TeamcityMessages::suiteFinished(const std::string &name, const std::string &flowid) {
113 openMsg("testSuiteFinished");
114 writeProperty("name", name);
115 if(flowid.length() > 0) {
116 writeProperty("flowId", flowid);
117 }
118
119 closeMsg();
120 }
121
testStarted(const std::string & name,const std::string & flowid,bool captureStandardOutput)122 void TeamcityMessages::testStarted(const std::string &name, const std::string &flowid, bool captureStandardOutput) {
123 openMsg("testStarted");
124 writeProperty("name", name);
125 if(flowid.length() > 0) {
126 writeProperty("flowId", flowid);
127 }
128
129 if(captureStandardOutput) {
130 writeProperty("captureStandardOutput", "true"); // false by default
131 }
132
133 closeMsg();
134 }
135
testFinished(const std::string & name,int durationMs,const std::string & flowid)136 void TeamcityMessages::testFinished(const std::string &name, int durationMs, const std::string &flowid) {
137 openMsg("testFinished");
138
139 writeProperty("name", name);
140
141 if(flowid.length() > 0) {
142 writeProperty("flowId", flowid);
143 }
144
145 if(durationMs >= 0) {
146 std::stringstream out(std::ios_base::out);
147 out << durationMs;
148 writeProperty("duration", out.str());
149 }
150
151 closeMsg();
152 }
153
testFailed(const std::string & name,const std::string & message,const std::string & details,const std::string & flowid)154 void TeamcityMessages::testFailed(const std::string &name, const std::string &message, const std::string &details, const std::string &flowid) {
155 openMsg("testFailed");
156 writeProperty("name", name);
157 writeProperty("message", message);
158 writeProperty("details", details);
159 if(flowid.length() > 0) {
160 writeProperty("flowId", flowid);
161 }
162
163 closeMsg();
164 }
165
testIgnored(const std::string & name,const std::string & message,const std::string & flowid)166 void TeamcityMessages::testIgnored(const std::string &name, const std::string &message, const std::string &flowid) {
167 openMsg("testIgnored");
168 writeProperty("name", name);
169 writeProperty("message", message);
170 if(flowid.length() > 0) {
171 writeProperty("flowId", flowid);
172 }
173
174 closeMsg();
175 }
176
testOutput(const std::string & name,const std::string & output,const std::string & flowid,bool isStdError)177 void TeamcityMessages::testOutput(const std::string &name, const std::string &output, const std::string &flowid, bool isStdError) {
178 openMsg(isStdError ? "testStdErr" : "testStdOut");
179 writeProperty("name", name);
180 writeProperty("out", output);
181 if(flowid.length() > 0) {
182 writeProperty("flowId", flowid);
183 }
184
185 closeMsg();
186 }
187
188 }
189 }
190