Module materialize.zippy.table_actions
Expand source code Browse git
# Copyright Materialize, Inc. and contributors. All rights reserved.
#
# Use of this software is governed by the Business Source License
# included in the LICENSE file at the root of this repository.
#
# As of the Change Date specified in that file, in accordance with
# the Business Source License, use of this software will be governed
# by the Apache License, Version 2.0.
import random
from typing import List, Set, Type
from materialize.mzcompose import Composition
from materialize.zippy.framework import Action, Capabilities, Capability
from materialize.zippy.mz_capabilities import MzIsRunning
from materialize.zippy.table_capabilities import TableExists
class CreateTable(Action):
@classmethod
def requires(self) -> Set[Type[Capability]]:
return {MzIsRunning}
def __init__(self, capabilities: Capabilities) -> None:
this_table = TableExists(name="table" + str(random.randint(1, 10)))
existing_tables = [
t for t in capabilities.get(TableExists) if t.name == this_table.name
]
if len(existing_tables) == 0:
self.new_table = True
self.table = this_table
elif len(existing_tables) == 1:
self.new_table = False
self.table = existing_tables[0]
else:
assert False
def run(self, c: Composition) -> None:
if self.new_table:
c.testdrive(
f"""
> CREATE TABLE {self.table.name} (f1 INTEGER);
> INSERT INTO {self.table.name} VALUES ({self.table.watermarks.high});
"""
)
def provides(self) -> List[Capability]:
return [self.table] if self.new_table else []
class ValidateTable(Action):
@classmethod
def requires(self) -> Set[Type[Capability]]:
return {MzIsRunning, TableExists}
def __init__(self, capabilities: Capabilities) -> None:
self.table = random.choice(capabilities.get(TableExists))
def run(self, c: Composition) -> None:
c.testdrive(
f"""
> SELECT MIN(f1), MAX(f1), COUNT(f1), COUNT(DISTINCT f1) FROM {self.table.name};
{self.table.watermarks.low} {self.table.watermarks.high} {(self.table.watermarks.high-self.table.watermarks.low)+1} {(self.table.watermarks.high-self.table.watermarks.low)+1}
"""
)
class DML(Action):
@classmethod
def requires(self) -> Set[Type[Capability]]:
return {MzIsRunning, TableExists}
def __init__(self, capabilities: Capabilities) -> None:
self.table = random.choice(capabilities.get(TableExists))
self.delta = random.randint(1, 100000)
class Insert(DML):
def run(self, c: Composition) -> None:
prev_high = self.table.watermarks.high
self.table.watermarks.high = prev_high + self.delta
c.testdrive(
f"> INSERT INTO {self.table.name} SELECT * FROM generate_series({prev_high + 1}, {self.table.watermarks.high});"
)
class ShiftForward(DML):
def run(self, c: Composition) -> None:
self.table.watermarks.shift(self.delta)
c.testdrive(f"> UPDATE {self.table.name} SET f1 = f1 + {self.delta};")
class ShiftBackward(DML):
def run(self, c: Composition) -> None:
self.table.watermarks.shift(-self.delta)
c.testdrive(f"> UPDATE {self.table.name} SET f1 = f1 - {self.delta};")
class DeleteFromHead(DML):
def run(self, c: Composition) -> None:
self.table.watermarks.high = max(
self.table.watermarks.high - self.delta, self.table.watermarks.low
)
c.testdrive(
f"> DELETE FROM {self.table.name} WHERE f1 > {self.table.watermarks.high};"
)
class DeleteFromTail(DML):
def run(self, c: Composition) -> None:
self.table.watermarks.low = min(
self.table.watermarks.low + self.delta, self.table.watermarks.high
)
c.testdrive(
f"> DELETE FROM {self.table.name} WHERE f1 < {self.table.watermarks.low};"
)
Classes
class CreateTable (capabilities: Capabilities)
-
Base class for an action that a Zippy test can take.
Construct a new action, possibly conditioning on the available capabilities.
Expand source code Browse git
class CreateTable(Action): @classmethod def requires(self) -> Set[Type[Capability]]: return {MzIsRunning} def __init__(self, capabilities: Capabilities) -> None: this_table = TableExists(name="table" + str(random.randint(1, 10))) existing_tables = [ t for t in capabilities.get(TableExists) if t.name == this_table.name ] if len(existing_tables) == 0: self.new_table = True self.table = this_table elif len(existing_tables) == 1: self.new_table = False self.table = existing_tables[0] else: assert False def run(self, c: Composition) -> None: if self.new_table: c.testdrive( f""" > CREATE TABLE {self.table.name} (f1 INTEGER); > INSERT INTO {self.table.name} VALUES ({self.table.watermarks.high}); """ ) def provides(self) -> List[Capability]: return [self.table] if self.new_table else []
Ancestors
Inherited members
class DML (capabilities: Capabilities)
-
Base class for an action that a Zippy test can take.
Construct a new action, possibly conditioning on the available capabilities.
Expand source code Browse git
class DML(Action): @classmethod def requires(self) -> Set[Type[Capability]]: return {MzIsRunning, TableExists} def __init__(self, capabilities: Capabilities) -> None: self.table = random.choice(capabilities.get(TableExists)) self.delta = random.randint(1, 100000)
Ancestors
Subclasses
Inherited members
class DeleteFromHead (capabilities: Capabilities)
-
Base class for an action that a Zippy test can take.
Construct a new action, possibly conditioning on the available capabilities.
Expand source code Browse git
class DeleteFromHead(DML): def run(self, c: Composition) -> None: self.table.watermarks.high = max( self.table.watermarks.high - self.delta, self.table.watermarks.low ) c.testdrive( f"> DELETE FROM {self.table.name} WHERE f1 > {self.table.watermarks.high};" )
Ancestors
Inherited members
class DeleteFromTail (capabilities: Capabilities)
-
Base class for an action that a Zippy test can take.
Construct a new action, possibly conditioning on the available capabilities.
Expand source code Browse git
class DeleteFromTail(DML): def run(self, c: Composition) -> None: self.table.watermarks.low = min( self.table.watermarks.low + self.delta, self.table.watermarks.high ) c.testdrive( f"> DELETE FROM {self.table.name} WHERE f1 < {self.table.watermarks.low};" )
Ancestors
Inherited members
class Insert (capabilities: Capabilities)
-
Base class for an action that a Zippy test can take.
Construct a new action, possibly conditioning on the available capabilities.
Expand source code Browse git
class Insert(DML): def run(self, c: Composition) -> None: prev_high = self.table.watermarks.high self.table.watermarks.high = prev_high + self.delta c.testdrive( f"> INSERT INTO {self.table.name} SELECT * FROM generate_series({prev_high + 1}, {self.table.watermarks.high});" )
Ancestors
Inherited members
class ShiftBackward (capabilities: Capabilities)
-
Base class for an action that a Zippy test can take.
Construct a new action, possibly conditioning on the available capabilities.
Expand source code Browse git
class ShiftBackward(DML): def run(self, c: Composition) -> None: self.table.watermarks.shift(-self.delta) c.testdrive(f"> UPDATE {self.table.name} SET f1 = f1 - {self.delta};")
Ancestors
Inherited members
class ShiftForward (capabilities: Capabilities)
-
Base class for an action that a Zippy test can take.
Construct a new action, possibly conditioning on the available capabilities.
Expand source code Browse git
class ShiftForward(DML): def run(self, c: Composition) -> None: self.table.watermarks.shift(self.delta) c.testdrive(f"> UPDATE {self.table.name} SET f1 = f1 + {self.delta};")
Ancestors
Inherited members
class ValidateTable (capabilities: Capabilities)
-
Base class for an action that a Zippy test can take.
Construct a new action, possibly conditioning on the available capabilities.
Expand source code Browse git
class ValidateTable(Action): @classmethod def requires(self) -> Set[Type[Capability]]: return {MzIsRunning, TableExists} def __init__(self, capabilities: Capabilities) -> None: self.table = random.choice(capabilities.get(TableExists)) def run(self, c: Composition) -> None: c.testdrive( f""" > SELECT MIN(f1), MAX(f1), COUNT(f1), COUNT(DISTINCT f1) FROM {self.table.name}; {self.table.watermarks.low} {self.table.watermarks.high} {(self.table.watermarks.high-self.table.watermarks.low)+1} {(self.table.watermarks.high-self.table.watermarks.low)+1} """ )
Ancestors
Inherited members