20
20
21
21
package com .apple .foundationdb .relational .yamltests .block ;
22
22
23
- import com .apple .foundationdb .relational .api .RelationalConnection ;
24
23
import com .apple .foundationdb .relational .util .Assert ;
25
24
import com .apple .foundationdb .relational .yamltests .CustomYamlConstructor ;
26
25
import com .apple .foundationdb .relational .yamltests .Matchers ;
27
26
import com .apple .foundationdb .relational .yamltests .YamlExecutionContext ;
28
27
29
- import org .apache .logging .log4j .LogManager ;
30
- import org .apache .logging .log4j .Logger ;
31
-
32
28
import javax .annotation .Nonnull ;
33
- import java .net .URI ;
34
- import java .sql .SQLException ;
35
- import java .util .Collection ;
36
- import java .util .List ;
37
- import java .util .function .Consumer ;
38
29
39
30
/**
40
- * Block is a single region in the YAMSQL file that can either be a {@link SetupBlock} or {@link TestBlock}.
31
+ * Block is a single region in the YAMSQL file that can either be a
32
+ * {@link FileOptions}, {@link SetupBlock} or {@link TestBlock}.
41
33
* <ul>
34
+ * <li> {@link FileOptions}: Controls whether a file should be run at all, and other configuration that runs before
35
+ * creating the connection.</li>
42
36
* <li> {@link SetupBlock}: It can be either a `setup` block or a `destruct` block. The motive of these block
43
37
* is to "setup" and "clean" the environment needed to run the `test-block`s. A Setup block consist of a list
44
38
* of commands.</li>
45
39
* <li> {@link TestBlock}: Defines a scope for a group of tests by setting the knobs that determines how those
46
40
* tests are run.</li>
47
41
* </ul>
48
- * <p>
49
- * Each block needs to be associated with a `connectionURI` which provides it with the address to the database to which
50
- * the block connects to for running its executables. The block does so through the
51
- * {@link com.apple.foundationdb.relational.yamltests.YamlRunner.YamlConnectionFactory}. A block is free to implement `how` and `when`
52
- * it wants to use the factory to create a connection and also manages the lifecycle of the established connection.
53
42
*/
54
- @ SuppressWarnings ({"PMD.GuardLogStatement" })
55
- public abstract class Block {
56
-
57
- private static final Logger logger = LogManager .getLogger (Block .class );
58
-
59
- static final String BLOCK_CONNECT = "connect" ;
60
-
61
- int lineNumber ;
62
- @ Nonnull
63
- YamlExecutionContext executionContext ;
64
- @ Nonnull
65
- private final URI connectionURI ;
66
- @ Nonnull
67
- final List <Consumer <RelationalConnection >> executables ;
68
-
69
- Block (int lineNumber , @ Nonnull List <Consumer <RelationalConnection >> executables , @ Nonnull URI connectionURI , @ Nonnull YamlExecutionContext executionContext ) {
70
- this .lineNumber = lineNumber ;
71
- this .executables = executables ;
72
- this .connectionURI = connectionURI ;
73
- this .executionContext = executionContext ;
74
- }
75
-
76
- public int getLineNumber () {
77
- return lineNumber ;
78
- }
79
-
80
- /**
81
- * Executes the executables from the parsed block in a single connection.
82
- */
83
- public abstract void execute ();
84
-
85
- protected final void executeExecutables (@ Nonnull Collection <Consumer <RelationalConnection >> list ) {
86
- connectToDatabaseAndExecute (connection -> list .forEach (t -> t .accept (connection )));
87
- }
88
-
89
- /**
90
- * Tries connecting to a database and execute the consumer using the established connection.
91
- *
92
- * @param consumer operations to be performed on the database using the established connection.
93
- */
94
- void connectToDatabaseAndExecute (Consumer <RelationalConnection > consumer ) {
95
- logger .debug ("🚠 Connecting to database: `{}`" , connectionURI );
96
- try (var connection = executionContext .getConnectionFactory ().getNewConnection (connectionURI )) {
97
- logger .debug ("✅ Connected to database: `{}`" , connectionURI );
98
- consumer .accept (connection );
99
- } catch (SQLException sqle ) {
100
- throw executionContext .wrapContext (sqle ,
101
- () -> String .format ("‼️ Error connecting to the database `%s` in block at line %d" , connectionURI , lineNumber ),
102
- "connection [" + connectionURI + "]" , getLineNumber ());
103
- }
104
- }
105
-
43
+ public interface Block {
106
44
/**
107
45
* Looks at the block to determine if its one of the valid blocks. If it is a valid one, parses it to that. This
108
46
* method dispatches the execution to the right block which takes care of reading from the block and initializing
109
- * the correctly configured {@link Block } for execution.
47
+ * the correctly configured {@link ConnectedBlock } for execution.
110
48
*
111
49
* @param document a region in the file
112
50
* @param executionContext information needed to carry out the execution
113
51
*/
114
- public static Block parse (@ Nonnull Object document , @ Nonnull YamlExecutionContext executionContext ) {
52
+ static Block parse (@ Nonnull Object document , @ Nonnull YamlExecutionContext executionContext ) {
115
53
final var blockObject = Matchers .map (document , "block" );
116
54
Assert .thatUnchecked (blockObject .size () == 1 , "Illegal Format: A block is expected to be a map of size 1" );
117
55
final var entry = Matchers .firstEntry (blockObject , "block key-value" );
@@ -124,8 +62,17 @@ public static Block parse(@Nonnull Object document, @Nonnull YamlExecutionContex
124
62
return TestBlock .parse (lineNumber , entry .getValue (), executionContext );
125
63
case SetupBlock .SchemaTemplateBlock .SCHEMA_TEMPLATE_BLOCK :
126
64
return SetupBlock .SchemaTemplateBlock .parse (lineNumber , entry .getValue (), executionContext );
65
+ case FileOptions .OPTIONS :
66
+ return FileOptions .parse (lineNumber , entry .getValue (), executionContext );
127
67
default :
128
68
throw new RuntimeException ("Cannot recognize the type of block" );
129
69
}
130
70
}
71
+
72
+ int getLineNumber ();
73
+
74
+ /**
75
+ * Executes the executables from the parsed block in a single connection.
76
+ */
77
+ void execute ();
131
78
}
0 commit comments