2424import java .io .IOException ;
2525import java .io .StringReader ;
2626import java .time .Instant ;
27- import java .util .ArrayList ;
27+ import java .util .AbstractMap ;
2828import java .util .Arrays ;
2929import java .util .HashMap ;
3030import java .util .List ;
3131import java .util .Map ;
32+ import java .util .stream .Collectors ;
33+ import java .util .stream .Stream ;
3234
3335import com .influxdb .Cancellable ;
3436import com .influxdb .query .InfluxQLQueryResult ;
3537import org .assertj .core .api .Assertions ;
3638import org .junit .jupiter .api .Test ;
37- import org .junit .platform .engine .TestTag ;
3839
3940class InfluxQLQueryApiImplTest {
4041
@@ -52,41 +53,117 @@ public boolean isCancelled() {
5253 @ Test
5354 void readInfluxQLResultWithTagCommas () throws IOException {
5455 InfluxQLQueryResult .Series .ValueExtractor extractValue = (columnName , rawValue , resultIndex , seriesName ) -> {
55- // System.out.println("DEBUG columnName: " + columnName + ", rawValue: " + rawValue + ", resultIndex: " + resultIndex + ", seriesName: " + seriesName);
5656 if (resultIndex == 0 && seriesName .equals ("data1" )){
5757 switch (columnName ){
5858 case "time" : return Instant .ofEpochSecond (Long .parseLong (rawValue ));
59- case "first" : return Double . valueOf ( rawValue );
60- //case "tags": return rawValue;
59+ case "first" :
60+ return Double . valueOf ( rawValue ) ;
6161 }
6262 }
6363 return rawValue ;
6464 };
6565
66- // Cheb,CZ should be \"Cheb,CZ\" a single tag value
67- // double quotes should work - from raw sample results commas should always be escaped
66+ List <String > testTags = Arrays .asList (
67+ "location=Cheb_CZ" , //simpleTag
68+ "region=us-east-1,host=server1" , // standardTags * 2
69+ "location=Cheb\\ ,\\ CZ" , // simpleTag with value comma and space
70+ "location=Cheb_CZ,branch=Munchen_DE" , // multiple tags with underscore
71+ "location=Cheb\\ ,\\ CZ,branch=Munchen\\ ,\\ DE" , // multiple tags with comma and space
72+ "model\\ ,\\ uin=C3PO" , // tag with comma space in key
73+ "model\\ ,\\ uin=Droid\\ , C3PO" , // tag with comma space in key and value
74+ "model\\ ,\\ uin=Droid\\ ,\\ C3PO,location=Cheb\\ ,\\ CZ,branch=Munchen\\ ,\\ DE" , // comma space in key and val
75+ "silly\\ ,long\\ ,tag=a\\ ,b\\ ,\\ c\\ ,\\ d" , // multiple commas in key and value
76+ "region=us\\ ,\\ east-1,host\\ ,\\ name=ser\\ ,\\ ver1" // legacy broken tags
77+ );
78+
79+ Map <String ,Map <String ,String >> expectedTagsMap = Stream .of (
80+ // 1. simpleTag
81+ new AbstractMap .SimpleImmutableEntry <>(testTags .get (0 ),
82+ new HashMap <String ,String >() {{
83+ put ("location" , "Cheb_CZ" );
84+ }}),
85+ // 2. standardTags * 2
86+ new AbstractMap .SimpleImmutableEntry <>(testTags .get (1 ),
87+ new HashMap <String ,String >() {{
88+ put ("region" , "us-east-1" );
89+ put ("host" , "server1" );
90+ }}),
91+ // 3. simpleTag with value comma and space
92+ new AbstractMap .SimpleImmutableEntry <>(testTags .get (2 ),
93+ new HashMap <String ,String >() {{
94+ put ("location" , "\" Cheb\\ ,\\ CZ\" " );
95+ }}),
96+ // 4. multiple tags with underscore
97+ new AbstractMap .SimpleImmutableEntry <>(testTags .get (3 ),
98+ new HashMap <String ,String >() {{
99+ put ("location" , "Cheb_CZ" );
100+ put ("branch" , "Munchen_DE" );
101+ }}),
102+ // 5. multiple tags with comma and space
103+ new AbstractMap .SimpleImmutableEntry <>(testTags .get (4 ),
104+ new HashMap <String ,String >() {{
105+ put ("location" , "\" Cheb\\ ,\\ CZ\" " );
106+ put ("branch" , "\" Munchen\\ ,\\ DE\" " );
107+ }}),
108+ // 6. tag with comma and space in key
109+ new AbstractMap .SimpleImmutableEntry <>(testTags .get (5 ),
110+ new HashMap <String ,String >() {{
111+ put ("\" model\\ ,\\ uin\" " , "C3PO" );
112+ }}),
113+ // 7. tag with comma and space in key and value
114+ new AbstractMap .SimpleImmutableEntry <>(testTags .get (6 ),
115+ new HashMap <String ,String >() {{
116+ put ("\" model\\ ,\\ uin\" " , "\" Droid\\ , C3PO\" " );
117+ }}),
118+ // 8. comma space in key and val with multiple tags
119+ new AbstractMap .SimpleImmutableEntry <>(testTags .get (7 ),
120+ new HashMap <String ,String >() {{
121+ put ("\" model\\ ,\\ uin\" " , "\" Droid\\ ,\\ C3PO\" " );
122+ put ("location" , "\" Cheb\\ ,\\ CZ\" " );
123+ put ("branch" , "\" Munchen\\ ,\\ DE\" " );
124+ }}),
125+ // 9. multiple commas in key and value
126+ new AbstractMap .SimpleImmutableEntry <>(testTags .get (8 ),
127+ new HashMap <String ,String >() {{
128+ put ("\" silly\\ ,long\\ ,tag\" " , "\" a\\ ,b\\ ,\\ c\\ ,\\ d\" " );
129+ }}),
130+ // legacy broken tags
131+ new AbstractMap .SimpleImmutableEntry <>(testTags .get (9 ),
132+ new HashMap <String ,String >() {{
133+ put ("region" , "\" us\\ ,\\ east-1\" " );
134+ put ("\" host\\ ,\\ name\" " , "\" ser\\ ,\\ ver1\" " );
135+ }})
136+ ).collect (Collectors .toMap (Map .Entry ::getKey , Map .Entry ::getValue ));
137+
68138 StringReader reader = new StringReader ("name,tags,time,first\n "
69- + "data1,\" location=Cheb_CZ\" ,1483225200,42\n "
70- + "data1,\" region=us-east-1,host=server1\" ,1483225200,13.57\n "
71- // + "data1,\"location=Cheb,CZ\",1483225200,42\n" // invalid - comma in value should be escaped
72- // + "data1,\"location=Cheb, CZ\",1483225200,42\n" // invalid - comma and space in value should be escaped
73- + "data1,\" location=Cheb\\ ,\\ CZ\" ,1483225200,42\n "
74- + "data1,\" location=Cheb_CZ,branch=Munchen_DE\" ,1483225200,42\n "
75- + "data1,\" location=Cheb\\ ,\\ CZ,branch=Munchen\\ ,\\ DE\" ,1483225200,42\n "
76- + "data1,\" model\\ ,\\ uin=C3PO\" ,1483225200,42\n "
77- + "data1,\" model\\ ,\\ uin=Droid\\ , C3PO\" ,1483225200,42\n "
78- + "data1,\" location=Cheb\\ ,\\ CZ,branch=Munchen\\ ,\\ DE\" ,1483225200,42\n "
79- + "data1,\" model\\ ,\\ uin=Droid\\ ,\\ C3PO,location=Cheb\\ ,\\ CZ,branch=Munchen\\ ,\\ DE\" ,1483225200,42\n "
80- + "data1,\" silly\\ ,long\\ ,tag=a\\ ,b\\ ,\\ c\\ ,\\ d\" ,1483225200,42\n "
139+ + "data1,\" " + testTags .get (0 ) + "\" ,1483225200,42\n "
140+ + "data1,\" " + testTags .get (1 ) + "\" ,1483225200,42\n "
141+ + "data1,\" " + testTags .get (2 ) + "\" ,1483225200,42\n "
142+ + "data1,\" " + testTags .get (3 ) + "\" ,1483225200,42\n "
143+ + "data1,\" " + testTags .get (4 ) + "\" ,1483225200,42\n "
144+ + "data1,\" " + testTags .get (5 ) + "\" ,1483225200,42\n "
145+ + "data1,\" " + testTags .get (6 ) + "\" ,1483225200,42\n "
146+ + "data1,\" " + testTags .get (7 ) + "\" ,1483225200,42\n "
147+ + "data1,\" " + testTags .get (8 ) + "\" ,1483225200,42\n "
81148 + "\n "
82149 + "name,tags,time,usage_user,usage_system\n "
83- + "cpu,\" region=us \\ , \\ east-1,host \\ , \\ name=ser \\ , \\ ver1 \" ,1483225200,13.57,1.4\n "
150+ + "cpu,\" " + testTags . get ( 9 ) + " \" ,1483225200,13.57,1.4\n "
84151 );
85152
86- // TODO meaningful asserts
87153 InfluxQLQueryResult result = InfluxQLQueryApiImpl .readInfluxQLResult (reader , NO_CANCELLING , extractValue );
88154 List <InfluxQLQueryResult .Result > results = result .getResults ();
89- // System.out.println("DEBUG results\n" + results.get(0).getSeries().get(0).getValues().get(0).getValueByKey("tags"));
155+ int index = 0 ;
156+ for (InfluxQLQueryResult .Result r : results ) {
157+ for (InfluxQLQueryResult .Series s : r .getSeries ()){
158+ Assertions .assertThat (s .getTags ()).isEqualTo (expectedTagsMap .get (testTags .get (index ++)));
159+ if (index < 9 ) {
160+ Assertions .assertThat (s .getColumns ()).containsOnlyKeys ("time" , "first" );
161+ InfluxQLQueryResult .Series .Record valRec = s .getValues ().get (0 );
162+ Assertions .assertThat (valRec .getValueByKey ("first" )).isEqualTo (Double .valueOf ("42.0" ));
163+ Assertions .assertThat (valRec .getValueByKey ("time" )).isEqualTo (Instant .ofEpochSecond (1483225200L ));
164+ }
165+ }
166+ }
90167 }
91168
92169 /*
0 commit comments