Skip to content

Commit 83e164b

Browse files
dinaltalIguazkatyakatsGal TopperGal Topper
authored
dev -> master (#567)
* IG-16745 - ignore grafana empty search requests (#561) * ignore grafana empty search requests * lint * IG-16807: making sure key passed in inferschema is valid (#558) * Fix error in tests. (#562) Co-authored-by: Gal Topper <galt@iguazio.com> * IG-16524: in case history directory was not created yet, return empty frame (#564) * IG-16666 (#563) * sort labels when creating tsdb frame * rename key -> labelName * IG-16911: returning error in case field in query is illegal (#566) * IG-17095 check client and server version match (#556) * check client and server version match * python styling * keep version in server instead of in api * fixes * ignore empty sessions * add env var for py tests * remove print * add flag to python makefile * remove flag from proto build * change env var to be passed in kwargs Co-authored-by: Dina Nimrodi <dinan@iguazio.com> Co-authored-by: Tal Neiman <33829179+talIguaz@users.noreply.github.com> Co-authored-by: Katya Katsenelenbogen <katyak@iguazio.com> Co-authored-by: Gal Topper <galt@iguaz.io> Co-authored-by: Gal Topper <galt@iguazio.com> Co-authored-by: Dina Nimrodi <dinan@iguazio.com>
1 parent 2e4513f commit 83e164b

26 files changed

+612
-237
lines changed

backends/kv/inferschema.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,10 @@ func schemaFromKeys(keyField string, rowSet []map[string]interface{}) (v3ioutils
183183
}
184184
return nil, errors.Errorf("could not determine which column is the table's primary-key attribute, because %s", reason)
185185
}
186+
} else {
187+
if val, ok := columnCanBeFullKey[keyField]; !ok || !val {
188+
return nil, errors.Errorf("%s is not one of the columns", keyField)
189+
}
186190
}
187191

188192
newSchema := v3ioutils.NewSchemaWithHashingBuckets(keyField, sortingKeyField, hashingBuckets)

backends/kv/inferschema_test.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,18 @@ func (suite *InferSchemaTestSuite) TestInferSchemaWithKeyLikeHashed() {
259259
suite.Require().Equal(0, concreteSchema.HashingBucketNum)
260260
}
261261

262+
func (suite *InferSchemaTestSuite) TestInferSchemaWithInvalidKey() {
263+
keyField := "invalid_key"
264+
rowSet := []map[string]interface{}{
265+
{"__name": "rocky", "name": "rocky", "animal": "dog", "age": 2},
266+
{"__name": "mocha", "name": "mocha", "animal": "dog", "age": 3},
267+
{"__name": "scratchy", "name": "scratchy", "animal": "cat", "age": 9},
268+
}
269+
_, err := schemaFromKeys(keyField, rowSet)
270+
suite.Require().Error(err)
271+
suite.Require().Equal("invalid_key is not one of the columns", err.Error())
272+
}
273+
262274
func TestInferSchemaTestSuite(t *testing.T) {
263275
suite.Run(t, new(InferSchemaTestSuite))
264276
}

backends/tsdb/reader.go

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ such restriction.
2121
package tsdb
2222

2323
import (
24+
"sort"
2425
"strings"
2526
"time"
2627

@@ -180,13 +181,19 @@ func (i *tsdbIterator) Next() bool {
180181
columns[i], _ = frame.Column(colName) // Because we are iterating over the Names() it is safe to discard the error
181182
}
182183

183-
for labelName, labelValue := range frame.Labels() {
184+
var labelNames []string
185+
labels := frame.Labels()
186+
for labelName := range labels {
187+
labelNames = append(labelNames, labelName)
188+
}
189+
sort.Strings(labelNames)
190+
for _, labelName := range labelNames {
184191
name := labelName
185192
if name == config.PrometheusMetricNameAttribute {
186193
name = "metric_name"
187194
}
188195

189-
icol, err := frames.NewLabelColumn(name, labelValue, frame.Len())
196+
icol, err := frames.NewLabelColumn(name, labels[labelName], frame.Len())
190197
if err != nil {
191198
i.err = err
192199
return false

backends/utils/history_server.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -364,6 +364,15 @@ func (m *HistoryServer) GetLogs(request *frames.HistoryRequest, out chan frames.
364364
iter, err := v3ioutils.NewFilesCursor(m.container, &v3io.GetContainerContentsInput{Path: m.LogsFolderPath + "/"})
365365

366366
if err != nil {
367+
if errWithStatusCode, ok := err.(v3ioerrors.ErrorWithStatusCode); ok &&
368+
errWithStatusCode.StatusCode() == http.StatusNotFound {
369+
frame, err := frames.NewFrameWithNullValues(nil, nil, nil, nil)
370+
if err != nil {
371+
return err
372+
}
373+
out <- frame
374+
return nil
375+
}
367376
return fmt.Errorf("Failed to list Frames History log folder %v for read, err: %v", m.LogsFolderPath, err)
368377
}
369378

clients/py/tests/test_client.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ def test_client(proto, cls):
3232
'password': 'duck season',
3333
}
3434

35-
client = v3f.Client(address, **session_params)
35+
client = v3f.Client(address, should_check_version=False, **session_params)
3636
assert client.__class__ is cls, 'wrong class'
3737
for key, value in session_params.items():
3838
key = 'url' if key == 'data_url' else key
@@ -52,7 +52,7 @@ def test_client_wrong_params(proto, cls):
5252
}
5353

5454
try:
55-
v3f.Client(address, **session_params)
55+
v3f.Client(address, should_check_version=False, **session_params)
5656
raise ValueError('expected fail but finished successfully')
5757
except ValueError:
5858
return

clients/py/tests/test_http.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ def post(self, *args, **kw):
4343
return self._read(*args, **kw)
4444
elif args[0].endswith('/write'):
4545
return self._write(*args, **kw)
46+
elif args[0].endswith('/version'):
47+
return self._version()
4648

4749
def _read(self, *args, **kw):
4850
io = BytesIO()
@@ -80,6 +82,21 @@ def json():
8082

8183
return Response
8284

85+
def _version(self):
86+
class Response:
87+
ok = True
88+
89+
@staticmethod
90+
def json():
91+
return {
92+
'version': 'test_version',
93+
}
94+
95+
return Response
96+
97+
def close(self):
98+
pass
99+
83100

84101
def test_read():
85102
address = 'https://nuclio.io'
@@ -141,4 +158,5 @@ def new_test_client(address='', session=None):
141158
return v3f.HTTPClient(
142159
address=address or 'http://example.com',
143160
session=session,
161+
should_check_version=False,
144162
)

clients/py/tests/test_v3io_frames.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,19 +33,19 @@ def setenv(key, value):
3333

3434

3535
def test_client():
36-
c = v3f.Client('localhost:8081')
36+
c = v3f.Client('localhost:8081', should_check_version=False)
3737
assert isinstance(c, v3f.gRPCClient), 'default is not grpc'
38-
c = v3f.Client('grpc://localhost:8081')
38+
c = v3f.Client('grpc://localhost:8081', should_check_version=False)
3939
assert isinstance(c, v3f.gRPCClient), 'not gRPC'
40-
c = v3f.Client('http://localhost:8081')
40+
c = v3f.Client('http://localhost:8081', should_check_version=False)
4141
assert isinstance(c, v3f.HTTPClient), 'not HTTP'
4242

4343

4444
def test_client_env():
4545
url = 'localhost:8080'
4646
data = json.dumps({'url': url})
4747
with setenv(v3f.SESSION_ENV_KEY, data):
48-
c = v3f.Client('localhost:8081')
48+
c = v3f.Client('localhost:8081', should_check_version=False)
4949

5050
assert c.session.url == url, 'missing URL from env'
5151

clients/py/v3io_frames/__init__.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434

3535
def Client(address='', data_url='', container='', user='',
3636
password='', token='', session_id='', frame_factory=pd.DataFrame,
37-
concat=pd.concat, persist_connection=False):
37+
concat=pd.concat, persist_connection=False, should_check_version=True):
3838
"""Creates a new Frames client object
3939
NOTE: User authentication must be done using any of the following methods:
4040
setting the `token` parameter or the V3IO_ACCESS_KEY environment variable
@@ -77,6 +77,8 @@ def Client(address='', data_url='', container='', user='',
7777
are made often. When True is used, due to the nature of the
7878
underlying clients, rapid instantiation of the client
7979
may cause failures (e.g. HTTP NewConnectionError)
80+
should_check_version (Optional) : str
81+
whether client and server version should be checked; default: true
8082
8183
Return Value
8284
----------
@@ -110,7 +112,7 @@ def Client(address='', data_url='', container='', user='',
110112

111113
cls = gRPCClient if protocol == 'grpc' else HTTPClient
112114
return cls(address, session, persist_connection,
113-
frame_factory=frame_factory, concat=concat)
115+
frame_factory=frame_factory, concat=concat, should_check_version=should_check_version)
114116

115117

116118
def session_from_env():

clients/py/v3io_frames/client.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ def is_null(self, index, column_name):
158158

159159
class ClientBase:
160160
def __init__(self, address, session, persist_connection=False,
161-
frame_factory=pd.DataFrame, concat=pd.concat):
161+
frame_factory=pd.DataFrame, concat=pd.concat, should_check_version=True):
162162
"""Creates a new Frames client object
163163
164164
Parameters
@@ -176,6 +176,8 @@ def __init__(self, address, session, persist_connection=False,
176176
DataFrame factory; currently, pandas and cuDF are supported
177177
concat : function
178178
Function for concatenating DataFrames; default: pandas concat
179+
should_check_version (Optional) : str
180+
whether client and server version should be checked; default: true
179181
180182
Return Value
181183
----------
@@ -186,6 +188,7 @@ def __init__(self, address, session, persist_connection=False,
186188
self._persist_connection = persist_connection
187189
self.frame_factory = frame_factory
188190
self.concat = concat
191+
self.should_check_version = should_check_version
189192

190193
def read(self, backend, table='', query='', columns=None, filter='',
191194
group_by='', limit=0, data_format='', row_layout=False,

clients/py/v3io_frames/errors.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414

1515
__all__ = [
1616
'Error', 'BadRequest', 'MessageError', 'ReadError', 'CreateError',
17-
'DeleteError', 'ExecuteError', 'WriteError'
17+
'DeleteError', 'ExecuteError', 'WriteError', 'HistoryError', 'VersionError'
1818
]
1919

2020

@@ -52,3 +52,7 @@ class ExecuteError(Error):
5252

5353
class HistoryError(Error):
5454
"""An error in querying history logs"""
55+
56+
57+
class VersionError(Error):
58+
"""An error in getting server version"""

0 commit comments

Comments
 (0)