| 
									
										
										
										
											2022-06-17 07:47:31 +02:00
										 |  |  | package loki | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							|  |  |  | 	"context" | 
					
						
							|  |  |  | 	"fmt" | 
					
						
							|  |  |  | 	"net/http" | 
					
						
							|  |  |  | 	"strings" | 
					
						
							|  |  |  | 	"testing" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	"github.com/stretchr/testify/require" | 
					
						
							|  |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func TestApiLogVolume(t *testing.T) { | 
					
						
							|  |  |  | 	response := []byte(` | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		"status": "success", | 
					
						
							|  |  |  | 		"data": { | 
					
						
							|  |  |  | 			"resultType" : "matrix", | 
					
						
							|  |  |  | 			"result": [] | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	`) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	t.Run("log-volume queries should set log-volume http header", func(t *testing.T) { | 
					
						
							|  |  |  | 		called := false | 
					
						
							|  |  |  | 		api := makeMockedAPI(200, "application/json", response, func(req *http.Request) { | 
					
						
							|  |  |  | 			called = true | 
					
						
							|  |  |  | 			require.Equal(t, "Source=logvolhist", req.Header.Get("X-Query-Tags")) | 
					
						
							|  |  |  | 		}) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-27 16:41:40 +01:00
										 |  |  | 		_, err := api.DataQuery(context.Background(), lokiQuery{Expr: "", SupportingQueryType: SupportingQueryLogsVolume, QueryType: QueryTypeRange}) | 
					
						
							|  |  |  | 		require.NoError(t, err) | 
					
						
							|  |  |  | 		require.True(t, called) | 
					
						
							|  |  |  | 	}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	t.Run("logs sample queries should set logs sample http header", func(t *testing.T) { | 
					
						
							|  |  |  | 		called := false | 
					
						
							|  |  |  | 		api := makeMockedAPI(200, "application/json", response, func(req *http.Request) { | 
					
						
							|  |  |  | 			called = true | 
					
						
							|  |  |  | 			require.Equal(t, "Source=logsample", req.Header.Get("X-Query-Tags")) | 
					
						
							|  |  |  | 		}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		_, err := api.DataQuery(context.Background(), lokiQuery{Expr: "", SupportingQueryType: SupportingQueryLogsSample, QueryType: QueryTypeRange}) | 
					
						
							|  |  |  | 		require.NoError(t, err) | 
					
						
							|  |  |  | 		require.True(t, called) | 
					
						
							|  |  |  | 	}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	t.Run("data sample queries should set data sample http header", func(t *testing.T) { | 
					
						
							|  |  |  | 		called := false | 
					
						
							|  |  |  | 		api := makeMockedAPI(200, "application/json", response, func(req *http.Request) { | 
					
						
							|  |  |  | 			called = true | 
					
						
							|  |  |  | 			require.Equal(t, "Source=datasample", req.Header.Get("X-Query-Tags")) | 
					
						
							|  |  |  | 		}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		_, err := api.DataQuery(context.Background(), lokiQuery{Expr: "", SupportingQueryType: SupportingQueryDataSample, QueryType: QueryTypeRange}) | 
					
						
							| 
									
										
										
										
											2022-06-17 07:47:31 +02:00
										 |  |  | 		require.NoError(t, err) | 
					
						
							|  |  |  | 		require.True(t, called) | 
					
						
							|  |  |  | 	}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	t.Run("non-log-volume queries should not set log-volume http header", func(t *testing.T) { | 
					
						
							|  |  |  | 		called := false | 
					
						
							|  |  |  | 		api := makeMockedAPI(200, "application/json", response, func(req *http.Request) { | 
					
						
							|  |  |  | 			called = true | 
					
						
							|  |  |  | 			require.Equal(t, "", req.Header.Get("X-Query-Tags")) | 
					
						
							|  |  |  | 		}) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-27 16:41:40 +01:00
										 |  |  | 		_, err := api.DataQuery(context.Background(), lokiQuery{Expr: "", SupportingQueryType: SupportingQueryNone, QueryType: QueryTypeRange}) | 
					
						
							| 
									
										
										
										
											2022-06-17 07:47:31 +02:00
										 |  |  | 		require.NoError(t, err) | 
					
						
							|  |  |  | 		require.True(t, called) | 
					
						
							|  |  |  | 	}) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func TestApiUrlHandling(t *testing.T) { | 
					
						
							|  |  |  | 	response := []byte(` | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		"status": "success", | 
					
						
							|  |  |  | 		"data": { | 
					
						
							|  |  |  | 			"resultType" : "matrix", | 
					
						
							|  |  |  | 			"result": [] | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	`) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	queryTestData := []struct { | 
					
						
							| 
									
										
										
										
											2022-06-17 09:47:49 +02:00
										 |  |  | 		name               string | 
					
						
							|  |  |  | 		dsUrl              string | 
					
						
							|  |  |  | 		rangeQueryPrefix   string | 
					
						
							|  |  |  | 		instantQueryPrefix string | 
					
						
							|  |  |  | 		metaUrl            string | 
					
						
							| 
									
										
										
										
											2022-06-17 07:47:31 +02:00
										 |  |  | 	}{ | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2022-06-17 09:47:49 +02:00
										 |  |  | 			name:               "no path in datasource-config", | 
					
						
							|  |  |  | 			dsUrl:              "http://localhost:3100", | 
					
						
							|  |  |  | 			rangeQueryPrefix:   "http://localhost:3100/loki/api/v1/query_range?", | 
					
						
							|  |  |  | 			instantQueryPrefix: "http://localhost:3100/loki/api/v1/query?", | 
					
						
							|  |  |  | 			metaUrl:            "http://localhost:3100/loki/api/v1/labels?start=1&end=2", | 
					
						
							| 
									
										
										
										
											2022-06-17 07:47:31 +02:00
										 |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2022-06-17 09:47:49 +02:00
										 |  |  | 			name:               "just a slash path in datasource-config", | 
					
						
							|  |  |  | 			dsUrl:              "http://localhost:3100/", | 
					
						
							|  |  |  | 			rangeQueryPrefix:   "http://localhost:3100/loki/api/v1/query_range?", | 
					
						
							|  |  |  | 			instantQueryPrefix: "http://localhost:3100/loki/api/v1/query?", | 
					
						
							|  |  |  | 			metaUrl:            "http://localhost:3100/loki/api/v1/labels?start=1&end=2", | 
					
						
							| 
									
										
										
										
											2022-06-17 07:47:31 +02:00
										 |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2022-06-17 09:47:49 +02:00
										 |  |  | 			name:               "when path-without-end-slash in datasource-config", | 
					
						
							|  |  |  | 			dsUrl:              "http://localhost:3100/a/b/c", | 
					
						
							|  |  |  | 			rangeQueryPrefix:   "http://localhost:3100/a/b/c/loki/api/v1/query_range?", | 
					
						
							|  |  |  | 			instantQueryPrefix: "http://localhost:3100/a/b/c/loki/api/v1/query?", | 
					
						
							|  |  |  | 			metaUrl:            "http://localhost:3100/a/b/c/loki/api/v1/labels?start=1&end=2", | 
					
						
							| 
									
										
										
										
											2022-06-17 07:47:31 +02:00
										 |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2022-06-17 09:47:49 +02:00
										 |  |  | 			name:               "path-with-end-slash in datasource-config", | 
					
						
							|  |  |  | 			dsUrl:              "http://localhost:3100/a/b/c/", | 
					
						
							|  |  |  | 			rangeQueryPrefix:   "http://localhost:3100/a/b/c/loki/api/v1/query_range?", | 
					
						
							|  |  |  | 			instantQueryPrefix: "http://localhost:3100/a/b/c/loki/api/v1/query?", | 
					
						
							|  |  |  | 			metaUrl:            "http://localhost:3100/a/b/c/loki/api/v1/labels?start=1&end=2", | 
					
						
							| 
									
										
										
										
											2022-06-17 07:47:31 +02:00
										 |  |  | 		}, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for _, test := range queryTestData { | 
					
						
							| 
									
										
										
										
											2022-06-17 09:47:49 +02:00
										 |  |  | 		t.Run("Loki should build the range-query URL correctly when "+test.name, func(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2022-06-17 07:47:31 +02:00
										 |  |  | 			called := false | 
					
						
							|  |  |  | 			api := makeMockedAPIWithUrl(test.dsUrl, 200, "application/json", response, func(req *http.Request) { | 
					
						
							|  |  |  | 				called = true | 
					
						
							|  |  |  | 				urlString := req.URL.String() | 
					
						
							| 
									
										
										
										
											2022-06-17 09:47:49 +02:00
										 |  |  | 				wantedPrefix := test.rangeQueryPrefix | 
					
						
							| 
									
										
										
										
											2022-06-17 07:47:31 +02:00
										 |  |  | 				failMessage := fmt.Sprintf(`wanted prefix: [%s], got string [%s]`, wantedPrefix, urlString) | 
					
						
							|  |  |  | 				require.True(t, strings.HasPrefix(urlString, wantedPrefix), failMessage) | 
					
						
							|  |  |  | 			}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			query := lokiQuery{ | 
					
						
							|  |  |  | 				QueryType: QueryTypeRange, | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			_, err := api.DataQuery(context.Background(), query) | 
					
						
							|  |  |  | 			require.NoError(t, err) | 
					
						
							|  |  |  | 			require.True(t, called) | 
					
						
							|  |  |  | 		}) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-17 09:47:49 +02:00
										 |  |  | 	for _, test := range queryTestData { | 
					
						
							|  |  |  | 		t.Run("Loki should build the instant-query URL correctly when "+test.name, func(t *testing.T) { | 
					
						
							|  |  |  | 			called := false | 
					
						
							|  |  |  | 			api := makeMockedAPIWithUrl(test.dsUrl, 200, "application/json", response, func(req *http.Request) { | 
					
						
							|  |  |  | 				called = true | 
					
						
							|  |  |  | 				urlString := req.URL.String() | 
					
						
							|  |  |  | 				wantedPrefix := test.instantQueryPrefix | 
					
						
							|  |  |  | 				failMessage := fmt.Sprintf(`wanted prefix: [%s], got string [%s]`, wantedPrefix, urlString) | 
					
						
							|  |  |  | 				require.True(t, strings.HasPrefix(urlString, wantedPrefix), failMessage) | 
					
						
							|  |  |  | 			}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			query := lokiQuery{ | 
					
						
							|  |  |  | 				QueryType: QueryTypeInstant, | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			_, err := api.DataQuery(context.Background(), query) | 
					
						
							|  |  |  | 			require.NoError(t, err) | 
					
						
							|  |  |  | 			require.True(t, called) | 
					
						
							|  |  |  | 		}) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-17 07:47:31 +02:00
										 |  |  | 	for _, test := range queryTestData { | 
					
						
							|  |  |  | 		t.Run("Loki should build the metadata query URL correctly when "+test.name, func(t *testing.T) { | 
					
						
							|  |  |  | 			called := false | 
					
						
							|  |  |  | 			api := makeMockedAPIWithUrl(test.dsUrl, 200, "application/json", response, func(req *http.Request) { | 
					
						
							|  |  |  | 				called = true | 
					
						
							|  |  |  | 				require.Equal(t, test.metaUrl, req.URL.String()) | 
					
						
							|  |  |  | 			}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			_, err := api.RawQuery(context.Background(), "/loki/api/v1/labels?start=1&end=2") | 
					
						
							|  |  |  | 			require.NoError(t, err) | 
					
						
							|  |  |  | 			require.True(t, called) | 
					
						
							|  |  |  | 		}) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2022-11-22 14:02:30 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | func TestApiReturnValues(t *testing.T) { | 
					
						
							|  |  |  | 	t.Run("Loki should return the right encoding", func(t *testing.T) { | 
					
						
							|  |  |  | 		called := false | 
					
						
							|  |  |  | 		api := makeCompressedMockedAPIWithUrl("http://localhost:3100", 200, "application/json", []byte("foo"), func(req *http.Request) { | 
					
						
							|  |  |  | 			called = true | 
					
						
							|  |  |  | 		}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		encodedBytes, err := api.RawQuery(context.Background(), "/loki/api/v1/labels?start=1&end=2") | 
					
						
							|  |  |  | 		require.NoError(t, err) | 
					
						
							|  |  |  | 		require.True(t, called) | 
					
						
							|  |  |  | 		require.Equal(t, "gzip", encodedBytes.Encoding) | 
					
						
							|  |  |  | 		require.Equal(t, []byte("foo"), encodedBytes.Body) | 
					
						
							|  |  |  | 	}) | 
					
						
							|  |  |  | } |