• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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