Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
N
neoppod
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Levin Zimmermann
neoppod
Commits
28e097c8
Commit
28e097c8
authored
Mar 12, 2021
by
Julien Muchembled
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
qa: when comparing replicas, checksum metadata & data rather than only keys
parent
60bcbc5c
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
46 additions
and
37 deletions
+46
-37
neo/storage/database/mysqldb.py
neo/storage/database/mysqldb.py
+8
-13
neo/storage/database/sqlite.py
neo/storage/database/sqlite.py
+4
-0
neo/tests/threaded/__init__.py
neo/tests/threaded/__init__.py
+29
-2
neo/tests/threaded/testReplication.py
neo/tests/threaded/testReplication.py
+0
-21
neo/tests/zodb/__init__.py
neo/tests/zodb/__init__.py
+5
-1
No files found.
neo/storage/database/mysqldb.py
View file @
28e097c8
...
@@ -858,8 +858,9 @@ class MySQLDatabaseManager(DatabaseManager):
...
@@ -858,8 +858,9 @@ class MySQLDatabaseManager(DatabaseManager):
r
=
self
.
query
(
'SELECT tid, oid FROM obj FORCE INDEX(tid)'
r
=
self
.
query
(
'SELECT tid, oid FROM obj FORCE INDEX(tid)'
' WHERE `partition` = %d AND tid <= %d'
' WHERE `partition` = %d AND tid <= %d'
' AND (tid = %d AND %d <= oid OR %d < tid)'
' AND (tid = %d AND %d <= oid OR %d < tid)'
' ORDER BY tid ASC, oid ASC LIMIT %d'
%
(
' ORDER BY tid ASC, oid ASC%s'
%
(
partition
,
u64
(
max_tid
),
min_tid
,
u64
(
min_oid
),
min_tid
,
length
))
partition
,
u64
(
max_tid
),
min_tid
,
u64
(
min_oid
),
min_tid
,
''
if
length
is
None
else
' LIMIT %s'
%
length
))
return
[(
p64
(
serial
),
p64
(
oid
))
for
serial
,
oid
in
r
]
return
[(
p64
(
serial
),
p64
(
oid
))
for
serial
,
oid
in
r
]
def
_getTIDList
(
self
,
offset
,
length
,
partition_list
):
def
_getTIDList
(
self
,
offset
,
length
,
partition_list
):
...
@@ -871,17 +872,11 @@ class MySQLDatabaseManager(DatabaseManager):
...
@@ -871,17 +872,11 @@ class MySQLDatabaseManager(DatabaseManager):
def
getReplicationTIDList
(
self
,
min_tid
,
max_tid
,
length
,
partition
):
def
getReplicationTIDList
(
self
,
min_tid
,
max_tid
,
length
,
partition
):
u64
=
util
.
u64
u64
=
util
.
u64
p64
=
util
.
p64
p64
=
util
.
p64
min_tid
=
u64
(
min_tid
)
r
=
self
.
query
(
"SELECT tid FROM trans"
max_tid
=
u64
(
max_tid
)
" WHERE `partition` = %s AND tid >= %s AND tid <= %s"
r
=
self
.
query
(
"""SELECT tid FROM trans
" ORDER BY tid ASC%s"
%
(
WHERE `partition` = %(partition)d
partition
,
u64
(
min_tid
),
u64
(
max_tid
),
AND tid >= %(min_tid)d AND tid <= %(max_tid)d
''
if
length
is
None
else
' LIMIT %s'
%
length
))
ORDER BY tid ASC LIMIT %(length)d"""
%
{
'partition'
:
partition
,
'min_tid'
:
min_tid
,
'max_tid'
:
max_tid
,
'length'
:
length
,
})
return
[
p64
(
t
[
0
])
for
t
in
r
]
return
[
p64
(
t
[
0
])
for
t
in
r
]
def
_updatePackFuture
(
self
,
oid
,
orig_serial
,
max_serial
):
def
_updatePackFuture
(
self
,
oid
,
orig_serial
,
max_serial
):
...
...
neo/storage/database/sqlite.py
View file @
28e097c8
...
@@ -593,6 +593,8 @@ class SQLiteDatabaseManager(DatabaseManager):
...
@@ -593,6 +593,8 @@ class SQLiteDatabaseManager(DatabaseManager):
u64
=
util
.
u64
u64
=
util
.
u64
p64
=
util
.
p64
p64
=
util
.
p64
min_tid
=
u64
(
min_tid
)
min_tid
=
u64
(
min_tid
)
if
length
is
None
:
length
=
-
1
return
[(
p64
(
serial
),
p64
(
oid
))
for
serial
,
oid
in
self
.
query
(
"""
\
return
[(
p64
(
serial
),
p64
(
oid
))
for
serial
,
oid
in
self
.
query
(
"""
\
SELECT tid, oid FROM obj
SELECT tid, oid FROM obj
WHERE partition=? AND tid<=?
WHERE partition=? AND tid<=?
...
@@ -611,6 +613,8 @@ class SQLiteDatabaseManager(DatabaseManager):
...
@@ -611,6 +613,8 @@ class SQLiteDatabaseManager(DatabaseManager):
p64
=
util
.
p64
p64
=
util
.
p64
min_tid
=
u64
(
min_tid
)
min_tid
=
u64
(
min_tid
)
max_tid
=
u64
(
max_tid
)
max_tid
=
u64
(
max_tid
)
if
length
is
None
:
length
=
-
1
return
[
p64
(
t
[
0
])
for
t
in
self
.
query
(
"""
\
return
[
p64
(
t
[
0
])
for
t
in
self
.
query
(
"""
\
SELECT tid FROM trans
SELECT tid FROM trans
WHERE partition=? AND ?<=tid AND tid<=?
WHERE partition=? AND ?<=tid AND tid<=?
...
...
neo/tests/threaded/__init__.py
View file @
28e097c8
...
@@ -16,10 +16,11 @@
...
@@ -16,10 +16,11 @@
# XXX: Consider using ClusterStates.STOPPING to stop clusters
# XXX: Consider using ClusterStates.STOPPING to stop clusters
import
os
,
random
,
select
,
socket
,
sys
,
tempfile
import
hashlib
,
os
,
random
,
select
,
socket
,
sys
,
tempfile
import
thread
,
threading
,
time
,
traceback
,
weakref
import
thread
,
threading
,
time
,
traceback
,
weakref
from
collections
import
deque
from
collections
import
deque
from
contextlib
import
contextmanager
from
contextlib
import
contextmanager
from
cPickle
import
dumps
from
email
import
message_from_string
from
email
import
message_from_string
from
itertools
import
count
from
itertools
import
count
from
functools
import
partial
,
wraps
from
functools
import
partial
,
wraps
...
@@ -35,7 +36,7 @@ from neo.lib.connection import BaseConnection, \
...
@@ -35,7 +36,7 @@ from neo.lib.connection import BaseConnection, \
from
neo.lib.connector
import
SocketConnector
,
ConnectorException
from
neo.lib.connector
import
SocketConnector
,
ConnectorException
from
neo.lib.handler
import
EventHandler
from
neo.lib.handler
import
EventHandler
from
neo.lib.locking
import
SimpleQueue
from
neo.lib.locking
import
SimpleQueue
from
neo.lib.protocol
import
uuid_str
,
\
from
neo.lib.protocol
import
ZERO_OID
,
ZERO_TID
,
MAX_TID
,
uuid_str
,
\
ClusterStates
,
Enum
,
NodeStates
,
NodeTypes
,
Packets
ClusterStates
,
Enum
,
NodeStates
,
NodeTypes
,
Packets
from
neo.lib.util
import
cached_property
,
parseMasterList
,
p64
from
neo.lib.util
import
cached_property
,
parseMasterList
,
p64
from
neo.master.recovery
import
RecoveryManager
from
neo.master.recovery
import
RecoveryManager
...
@@ -482,6 +483,17 @@ class StorageApplication(ServerNode, neo.storage.app.Application):
...
@@ -482,6 +483,17 @@ class StorageApplication(ServerNode, neo.storage.app.Application):
(
r
,),
=
self
.
dm
.
query
(
"SELECT COUNT(*) FROM "
+
table
)
(
r
,),
=
self
.
dm
.
query
(
"SELECT COUNT(*) FROM "
+
table
)
return
r
return
r
def
checksumPartition
(
self
,
partition
,
max_tid
=
MAX_TID
):
dm
=
self
.
dm
args
=
ZERO_TID
,
max_tid
,
None
,
partition
trans
=
hashlib
.
md5
()
for
tid
in
dm
.
getReplicationTIDList
(
*
args
):
trans
.
update
(
dumps
(
dm
.
getTransaction
(
tid
)))
obj
=
hashlib
.
md5
()
for
tid
,
oid
in
dm
.
getReplicationObjectList
(
*
args
,
min_oid
=
ZERO_OID
):
obj
.
update
(
dumps
(
dm
.
fetchObject
(
oid
,
tid
)))
return
trans
.
hexdigest
(),
obj
.
hexdigest
()
class
ClientApplication
(
Node
,
neo
.
client
.
app
.
Application
):
class
ClientApplication
(
Node
,
neo
.
client
.
app
.
Application
):
max_reconnection_to_master
=
10
max_reconnection_to_master
=
10
...
@@ -1186,6 +1198,21 @@ class NEOThreadedTest(NeoTestBase):
...
@@ -1186,6 +1198,21 @@ class NEOThreadedTest(NeoTestBase):
assertStartsWith
(
msg
.
pop
(
0
),
' %s'
%
x
)
assertStartsWith
(
msg
.
pop
(
0
),
' %s'
%
x
)
self
.
assertFalse
(
expected
)
self
.
assertFalse
(
expected
)
def
checkPartitionReplicated
(
self
,
source
,
destination
,
partition
,
**
kw
):
self
.
assertEqual
(
source
.
checksumPartition
(
partition
,
**
kw
),
destination
.
checksumPartition
(
partition
,
**
kw
))
def
checkReplicas
(
self
,
cluster
):
pt
=
cluster
.
primary_master
.
pt
storage_dict
=
{
x
.
uuid
:
x
for
x
in
cluster
.
storage_list
}
for
offset
in
xrange
(
pt
.
getPartitions
()):
checksum_list
=
[
storage_dict
[
x
.
getUUID
()].
checksumPartition
(
offset
)
for
x
in
pt
.
getCellList
(
offset
)]
self
.
assertLess
(
1
,
len
(
checksum_list
))
self
.
assertEqual
(
1
,
len
(
set
(
checksum_list
)),
(
offset
,
checksum_list
))
class
ThreadId
(
list
):
class
ThreadId
(
list
):
...
...
neo/tests/threaded/testReplication.py
View file @
28e097c8
...
@@ -60,16 +60,6 @@ def backup_test(partitions=1, upstream_kw={}, backup_kw={}):
...
@@ -60,16 +60,6 @@ def backup_test(partitions=1, upstream_kw={}, backup_kw={}):
class
ReplicationTests
(
NEOThreadedTest
):
class
ReplicationTests
(
NEOThreadedTest
):
def
checksumPartition
(
self
,
storage
,
partition
,
max_tid
=
MAX_TID
):
dm
=
storage
.
dm
args
=
partition
,
None
,
ZERO_TID
,
max_tid
return
dm
.
checkTIDRange
(
*
args
),
\
dm
.
checkSerialRange
(
min_oid
=
ZERO_OID
,
*
args
)
def
checkPartitionReplicated
(
self
,
source
,
destination
,
partition
,
**
kw
):
self
.
assertEqual
(
self
.
checksumPartition
(
source
,
partition
,
**
kw
),
self
.
checksumPartition
(
destination
,
partition
,
**
kw
))
def
checkBackup
(
self
,
cluster
,
**
kw
):
def
checkBackup
(
self
,
cluster
,
**
kw
):
upstream_pt
=
cluster
.
upstream
.
primary_master
.
pt
upstream_pt
=
cluster
.
upstream
.
primary_master
.
pt
pt
=
cluster
.
primary_master
.
pt
pt
=
cluster
.
primary_master
.
pt
...
@@ -89,17 +79,6 @@ class ReplicationTests(NEOThreadedTest):
...
@@ -89,17 +79,6 @@ class ReplicationTests(NEOThreadedTest):
checked
+=
1
checked
+=
1
return
checked
return
checked
def
checkReplicas
(
self
,
cluster
):
pt
=
cluster
.
primary_master
.
pt
storage_dict
=
{
x
.
uuid
:
x
for
x
in
cluster
.
storage_list
}
for
offset
in
xrange
(
pt
.
getPartitions
()):
checksum_list
=
[
self
.
checksumPartition
(
storage_dict
[
x
.
getUUID
()],
offset
)
for
x
in
pt
.
getCellList
(
offset
)]
self
.
assertLess
(
1
,
len
(
checksum_list
))
self
.
assertEqual
(
1
,
len
(
set
(
checksum_list
)),
(
offset
,
checksum_list
))
def
testBackupNormalCase
(
self
):
def
testBackupNormalCase
(
self
):
np
=
7
np
=
7
nr
=
2
nr
=
2
...
...
neo/tests/zodb/__init__.py
View file @
28e097c8
...
@@ -21,7 +21,11 @@ functional = int(os.getenv('NEO_TEST_ZODB_FUNCTIONAL', 0))
...
@@ -21,7 +21,11 @@ functional = int(os.getenv('NEO_TEST_ZODB_FUNCTIONAL', 0))
if
functional
:
if
functional
:
from
..functional
import
NEOCluster
,
NEOFunctionalTest
as
TestCase
from
..functional
import
NEOCluster
,
NEOFunctionalTest
as
TestCase
else
:
else
:
from
..threaded
import
NEOCluster
,
NEOThreadedTest
as
TestCase
from
..threaded
import
NEOCluster
,
NEOThreadedTest
x
=
dict
.
fromkeys
(
x
for
x
in
dir
(
NEOThreadedTest
)
if
x
.
startswith
(
'check'
))
assert
x
TestCase
=
type
(
''
,
(
NEOThreadedTest
,),
x
)
del
x
class
ZODBTestCase
(
TestCase
):
class
ZODBTestCase
(
TestCase
):
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment