Esempio n. 1
0
        public async Task Update_MissingScript()
        {
            // Verify that we detect the situation where the script folder has a keyspace
            // creation script but there's a version gap in the remaining scripts.

            var keyspaceName = GetUniqueKeyspaceName();
            var scripts      =
                new string[]
            {
                "CREATE KEYSPACE ${keyspace};",
                "CREATE my_table-0 (name text);",
                "CREATE my_table-1 (name text);",
                "CREATE my_table-2 (name text);"
            };

            using (var tempFolder = await PersistSchemaScriptsAsync(scripts))
            {
                File.Delete(Path.Combine(tempFolder.Path, "schema-2.script"));

                using (var schemaManager = new SchemaManager(cassandra, keyspaceName, tempFolder.Path))
                {
                    await schemaManager.CreateKeyspaceAsync();

                    await Assert.ThrowsAsync <FileNotFoundException>(async() => await schemaManager.UpgradeKeyspaceAsync());
                }
            }
        }
Esempio n. 2
0
        public async Task Create()
        {
            // Verify that the schema manager can create a keyspace.

            var keyspaceName = GetUniqueKeyspaceName();
            var scripts      = new string[]
            {
                "CREATE KEYSPACE ${keyspace};"
            };

            using (var tempFolder = await PersistSchemaScriptsAsync(scripts))
            {
                using (var schemaManager = new SchemaManager(cassandra, keyspaceName, tempFolder.Path))
                {
                    Assert.True(await schemaManager.CreateKeyspaceAsync());

                    var status = await schemaManager.GetStatusAsync();

                    Assert.Equal(SchemaStatus.ExistsWithSchema, status.SchemaStatus);
                    Assert.Equal(0, status.Version);
                    Assert.Equal(0, status.MaxVersion);
                    Assert.True(status.IsCurrent);
                }
            }
        }
Esempio n. 3
0
        public async Task EmbeddedScripts()
        {
            // Verify that we can process scripts loaded from embedded resources.

            var keyspaceName = GetUniqueKeyspaceName();

            using (var schemaManager = new SchemaManager(cassandra, keyspaceName, Assembly.GetExecutingAssembly().GetResourceFileSystem("Test.Neon.Cassandra.Scripts")))
            {
                await schemaManager.CreateKeyspaceAsync();

                await schemaManager.UpgradeKeyspaceAsync();
            }
        }
Esempio n. 4
0
        public async Task Create_KeyspaceExists()
        {
            // Verify that the schema manager keyspace creation handles the case
            // where the keyspace already exists and has a proper DBINFO table.

            var keyspaceName = GetUniqueKeyspaceName();
            var scripts      = new string[]
            {
                "CREATE KEYSPACE ${keyspace};"
            };

            using (var tempFolder = await PersistSchemaScriptsAsync(scripts))
            {
                using (var schemaManager = new SchemaManager(cassandra, keyspaceName, tempFolder.Path))
                {
                    Assert.True(await schemaManager.CreateKeyspaceAsync());

                    var status = await schemaManager.GetStatusAsync();

                    Assert.Equal(SchemaStatus.ExistsWithSchema, status.SchemaStatus);
                    Assert.Equal(0, status.Version);
                    Assert.Equal(0, status.MaxVersion);
                    Assert.True(status.IsCurrent);

                    // CreateKeyspaceAsync() should return FALSE here
                    // because that keyspace already exists.

                    Assert.False(await schemaManager.CreateKeyspaceAsync());

                    status = await schemaManager.GetStatusAsync();

                    Assert.Equal(SchemaStatus.ExistsWithSchema, status.SchemaStatus);
                    Assert.Equal(0, status.Version);
                    Assert.Equal(0, status.MaxVersion);
                    Assert.True(status.IsCurrent);
                }
            }
        }
Esempio n. 5
0
        public async Task Update_MissingDBInfo()
        {
            // Verify that update detects when the target keyspace doesn't
            // have a DBINFO table.

            var keyspaceName = GetUniqueKeyspaceName();
            var scripts      = new string[]
            {
                "CREATE KEYSPACE ${keyspace};",
                "CREATE TABLE people (name text, age integer);"
            };

            using (var tempFolder = await PersistSchemaScriptsAsync(scripts))
            {
                using (var schemaManager = new SchemaManager(cassandra, keyspaceName, tempFolder.Path))
                {
                    Assert.True(await schemaManager.CreateKeyspaceAsync());

                    var status = await schemaManager.GetStatusAsync();

                    Assert.Equal(SchemaStatus.ExistsWithSchema, status.SchemaStatus);
                    Assert.Equal(0, status.Version);
                    Assert.Equal(1, status.MaxVersion);
                    Assert.False(status.IsCurrent);

                    // Drop the DBINFO table for the test.

                    await ExecuteWithKeyspaceAsync(keyspaceName,
                                                   async() =>
                    {
                        await cassandra.ExecuteAsync($"DROP TABLE {SchemaManager.DbInfoTableName};");
                    });

                    status = await schemaManager.GetStatusAsync();

                    Assert.Equal(SchemaStatus.ExistsNoSchema, status.SchemaStatus);

                    await Assert.ThrowsAsync <SchemaManagerException>(async() => await schemaManager.UpgradeKeyspaceAsync());
                }
            }
        }
Esempio n. 6
0
        public async Task Update_InvalidDBInfo()
        {
            // Verify that update detects when the target keyspace has a DBINFO
            // table but that it's invalid.

            var keyspaceName = GetUniqueKeyspaceName();
            var scripts      = new string[]
            {
                "CREATE KEYSPACE ${keyspace};",
                "CREATE TABLE people (name text, age integer);"
            };

            using (var tempFolder = await PersistSchemaScriptsAsync(scripts))
            {
                using (var schemaManager = new SchemaManager(cassandra, keyspaceName, tempFolder.Path))
                {
                    Assert.True(await schemaManager.CreateKeyspaceAsync());

                    var status = await schemaManager.GetStatusAsync();

                    Assert.Equal(SchemaStatus.ExistsWithSchema, status.SchemaStatus);
                    Assert.Equal(0, status.Version);
                    Assert.Equal(1, status.MaxVersion);
                    Assert.False(status.IsCurrent);

                    // Set a negative version in DBINFO and verify the exception.

                    await ExecuteWithKeyspaceAsync(keyspaceName,
                                                   async() =>
                    {
                        await cassandra.ExecuteAsync($"UPDATE {SchemaManager.DbInfoTableName} SET version = -1 WHERE key = 1;");
                    });

                    await Assert.ThrowsAsync <SchemaManagerException>(async() => await schemaManager.GetStatusAsync());
                }
            }
        }
Esempio n. 7
0
        public async Task Updater_Error()
        {
            // Verify that we can detect when another updater appears to be
            // failed due to a simulated script execution error.

            var keyspaceName = GetUniqueKeyspaceName();
            var scripts      =
                new string[]
            {
                "CREATE KEYSPACE ${keyspace};"
            };

            using (var tempFolder = await PersistSchemaScriptsAsync(scripts))
            {
                using (var schemaManager = new SchemaManager(cassandra, keyspaceName, tempFolder.Path))
                {
                    // Create the keyspace.

                    await schemaManager.CreateKeyspaceAsync();

                    var status = await schemaManager.GetStatusAsync();

                    Assert.True(status.IsCurrent);

                    // Update the DBINFO table to make it appear that another updater failed.

                    await ExecuteWithKeyspaceAsync(keyspaceName,
                                                   async() =>
                    {
                        await cassandra.ExecuteAsync($"UPDATE {SchemaManager.DbInfoTableName} SET updater = 'another-updater', update_start_utc = currenttimestamp(), update_finish_utc = NULL, error = 'Something bad happened!' WHERE key = 1;");
                    });
                }
            }

            // Create a new schema manager with upgrade scripts and ensure that
            // the updates are applied.

            scripts =
                new string[]
            {
                "CREATE KEYSPACE ${keyspace};",
                @"CREATE TABLE my_table (key integer, version integer, PRIMARY KEY (key));
GO           
INSERT INTO my_table (key, version) values (1, 1);",
                "UPDATE my_table SET version = 2 WHERE key = 1;",
                "UPDATE my_table SET version = 3 WHERE key = 1;",
                "UPDATE my_table SET version = 4 WHERE key = 1;",
            };

            using (var tempFolder = await PersistSchemaScriptsAsync(scripts))
            {
                using (var schemaManager = new SchemaManager(cassandra, keyspaceName, tempFolder.Path))
                {
                    var status = await schemaManager.GetStatusAsync();

                    Assert.Equal(SchemaStatus.UpgradeError, status.SchemaStatus);
                    Assert.Equal(0, status.Version);
                    Assert.Equal(4, status.MaxVersion);
                    Assert.Equal("Something bad happened!", status.Error);

                    // Attempt to apply the updates.  This should fail because another updater
                    // appears to be updating.

                    await Assert.ThrowsAsync <SchemaManagerException>(async() => await schemaManager.UpgradeKeyspaceAsync());

                    // Try updating again with [force=true].  It should work this time.

                    Assert.Equal(4, await schemaManager.UpgradeKeyspaceAsync(force: true));

                    status = await schemaManager.GetStatusAsync();

                    Assert.Equal(4, status.Version);
                    await ExecuteWithKeyspaceAsync(keyspaceName,
                                                   async() =>
                    {
                        var row = (await cassandra.ExecuteAsync("SELECT version FROM my_table WHERE key = 1;")).Single();

                        Assert.Equal(4, row.GetValue <int>("version"));
                    });
                }
            }
        }
Esempio n. 8
0
        public async Task Scripts_WithLeadingZeros()
        {
            // Verify that we support script file names with leading zeros in
            // the version numbers.

            // Create the initial keyspace and verify that it's up to date.

            var keyspaceName = GetUniqueKeyspaceName();
            var scripts      =
                new string[]
            {
                "CREATE KEYSPACE ${keyspace};"
            };

            using (var tempFolder = await PersistSchemaScriptsWithZerosAsync(scripts))
            {
                using (var schemaManager = new SchemaManager(cassandra, keyspaceName, tempFolder.Path))
                {
                    await schemaManager.CreateKeyspaceAsync();

                    var status = await schemaManager.GetStatusAsync();

                    Assert.True(status.IsCurrent);
                }
            }

            // Create a new schema manager with upgrade scripts and ensure that
            // the updates are applied.

            scripts =
                new string[]
            {
                "CREATE KEYSPACE ${keyspace};",
                @"CREATE TABLE my_table (key integer, version integer, PRIMARY KEY (key));
GO           
INSERT INTO my_table (key, version) values (1, 1);",
                "UPDATE my_table SET version = 2 WHERE key = 1;",
                "UPDATE my_table SET version = 3 WHERE key = 1;",
                "UPDATE my_table SET version = 4 WHERE key = 1;",
            };

            using (var tempFolder = await PersistSchemaScriptsWithZerosAsync(scripts))
            {
                using (var schemaManager = new SchemaManager(cassandra, keyspaceName, tempFolder.Path))
                {
                    var status = await schemaManager.GetStatusAsync();

                    Assert.Equal(SchemaStatus.ExistsWithSchema, status.SchemaStatus);
                    Assert.Equal(0, status.Version);
                    Assert.Equal(4, status.MaxVersion);
                    Assert.Equal(4, await schemaManager.UpgradeKeyspaceAsync());

                    // Verify that the updates were actually applied.

                    await ExecuteWithKeyspaceAsync(keyspaceName,
                                                   async() =>
                    {
                        var row = (await cassandra.ExecuteAsync("SELECT version FROM my_table WHERE key = 1;")).Single();

                        Assert.Equal(4, row.GetValue <int>("version"));
                    });
                }
            }

            // Add a couple additional upgrade scripts and verify.

            scripts =
                new string[]
            {
                "CREATE KEYSPACE ${keyspace};",
                @"CREATE TABLE my_table (key integer, version integer, PRIMARY KEY (key));
GO           
INSERT INTO my_table (key, version) values (1, 1);",
                "UPDATE my_table SET version = 2 WHERE key = 1;",
                "UPDATE my_table SET version = 3 WHERE key = 1;",
                "UPDATE my_table SET version = 4 WHERE key = 1;",
                "UPDATE my_table SET version = 5 WHERE key = 1;",
                "UPDATE my_table SET version = 6 WHERE key = 1;",
            };

            using (var tempFolder = await PersistSchemaScriptsWithZerosAsync(scripts))
            {
                using (var schemaManager = new SchemaManager(cassandra, keyspaceName, tempFolder.Path))
                {
                    var status = await schemaManager.GetStatusAsync();

                    Assert.Equal(SchemaStatus.ExistsWithSchema, status.SchemaStatus);
                    Assert.Equal(4, status.Version);
                    Assert.Equal(6, status.MaxVersion);
                    Assert.Equal(6, await schemaManager.UpgradeKeyspaceAsync());

                    // Verify that the updates were actually applied.

                    await ExecuteWithKeyspaceAsync(keyspaceName,
                                                   async() =>
                    {
                        var row = (await cassandra.ExecuteAsync("SELECT version FROM my_table WHERE key = 1;")).Single();

                        Assert.Equal(6, row.GetValue <int>("version"));
                    });
                }
            }
        }
Esempio n. 9
0
        public async Task Update_Stop_Error()
        {
            // Verify that we're not allowed to stop at a version lower
            // than the current keyspace version.

            var keyspaceName = GetUniqueKeyspaceName();
            var scripts      =
                new string[]
            {
                "CREATE KEYSPACE ${keyspace};"
            };

            using (var tempFolder = await PersistSchemaScriptsAsync(scripts))
            {
                using (var schemaManager = new SchemaManager(cassandra, keyspaceName, tempFolder.Path))
                {
                    await schemaManager.CreateKeyspaceAsync();

                    var status = await schemaManager.GetStatusAsync();

                    Assert.True(status.IsCurrent);
                }
            }

            // Create a new schema manager with upgrade scripts and ensure that
            // the updates are applied.

            scripts =
                new string[]
            {
                "CREATE KEYSPACE ${keyspace};",
                @"CREATE TABLE my_table (key integer, version integer, PRIMARY KEY (key));
GO           
INSERT INTO my_table (key, version) values (1, 1);",
                "UPDATE my_table SET version = 2 WHERE key = 1;",
                "UPDATE my_table SET version = 3 WHERE key = 1;",
                "UPDATE my_table SET version = 4 WHERE key = 1;",
            };

            using (var tempFolder = await PersistSchemaScriptsAsync(scripts))
            {
                using (var schemaManager = new SchemaManager(cassandra, keyspaceName, tempFolder.Path))
                {
                    var status = await schemaManager.GetStatusAsync();

                    Assert.Equal(SchemaStatus.ExistsWithSchema, status.SchemaStatus);
                    Assert.Equal(0, status.Version);
                    Assert.Equal(4, status.MaxVersion);

                    // Apply all of the updates.

                    Assert.Equal(4, await schemaManager.UpgradeKeyspaceAsync());

                    status = await schemaManager.GetStatusAsync();

                    Assert.Equal(4, status.Version);
                    await ExecuteWithKeyspaceAsync(keyspaceName,
                                                   async() =>
                    {
                        var row = (await cassandra.ExecuteAsync("SELECT version FROM my_table WHERE key = 1;")).Single();

                        Assert.Equal(4, row.GetValue <int>("version"));
                    });

                    // Verify that we're not allowed to stop at an update that's
                    // already been applied.

                    await Assert.ThrowsAsync <SchemaManagerException>(async() => await schemaManager.UpgradeKeyspaceAsync(stopVersion: 2));

                    // Verify that the keyspace version hasn't changed.

                    status = await schemaManager.GetStatusAsync();

                    Assert.Equal(4, status.Version);
                    await ExecuteWithKeyspaceAsync(keyspaceName,
                                                   async() =>
                    {
                        var row = (await cassandra.ExecuteAsync("SELECT version FROM my_table WHERE key = 1;")).Single();

                        Assert.Equal(4, row.GetValue <int>("version"));
                    });
                }
            }
        }
Esempio n. 10
0
        public async Task Update_Stop()
        {
            // Verify that we can stop updates at a specific version.

            var keyspaceName = GetUniqueKeyspaceName();
            var scripts      =
                new string[]
            {
                "CREATE KEYSPACE ${keyspace};"
            };

            using (var tempFolder = await PersistSchemaScriptsAsync(scripts))
            {
                using (var schemaManager = new SchemaManager(cassandra, keyspaceName, tempFolder.Path))
                {
                    await schemaManager.CreateKeyspaceAsync();

                    var status = await schemaManager.GetStatusAsync();

                    Assert.True(status.IsCurrent);
                }
            }

            // Create a new schema manager with upgrade scripts and ensure that
            // the updates are applied.

            scripts =
                new string[]
            {
                "CREATE KEYSPACE ${keyspace};",
                @"CREATE TABLE my_table (key integer, version integer, PRIMARY KEY (key));
GO           
INSERT INTO my_table (key, version) values (1, 1);",
                "UPDATE my_table SET version = 2 WHERE key = 1;",
                "UPDATE my_table SET version = 3 WHERE key = 1;",
                "UPDATE my_table SET version = 4 WHERE key = 1;",
            };

            using (var tempFolder = await PersistSchemaScriptsAsync(scripts))
            {
                using (var schemaManager = new SchemaManager(cassandra, keyspaceName, tempFolder.Path))
                {
                    var status = await schemaManager.GetStatusAsync();

                    Assert.Equal(SchemaStatus.ExistsWithSchema, status.SchemaStatus);
                    Assert.Equal(0, status.Version);
                    Assert.Equal(4, status.MaxVersion);

                    // Verify that only the updates up to version=2 are applied.

                    Assert.Equal(2, await schemaManager.UpgradeKeyspaceAsync(stopVersion: 2));

                    status = await schemaManager.GetStatusAsync();

                    Assert.Equal(2, status.Version);
                    await ExecuteWithKeyspaceAsync(keyspaceName,
                                                   async() =>
                    {
                        var row = (await cassandra.ExecuteAsync("SELECT version FROM my_table WHERE key = 1;")).Single();

                        Assert.Equal(2, row.GetValue <int>("version"));
                    });

                    // Apply the remaining updates and verify.

                    Assert.Equal(4, await schemaManager.UpgradeKeyspaceAsync());

                    status = await schemaManager.GetStatusAsync();

                    Assert.Equal(4, status.Version);
                    await ExecuteWithKeyspaceAsync(keyspaceName,
                                                   async() =>
                    {
                        var row = (await cassandra.ExecuteAsync("SELECT version FROM my_table WHERE key = 1;")).Single();

                        Assert.Equal(4, row.GetValue <int>("version"));
                    });
                }
            }
        }
Esempio n. 11
0
        public async Task Update_NotRequired()
        {
            // Verify that update does not apply updates that have already
            // been applied.

            var keyspaceName = GetUniqueKeyspaceName();
            var scripts      =
                new string[]
            {
                "CREATE KEYSPACE ${keyspace};"
            };

            using (var tempFolder = await PersistSchemaScriptsAsync(scripts))
            {
                using (var schemaManager = new SchemaManager(cassandra, keyspaceName, tempFolder.Path))
                {
                    await schemaManager.CreateKeyspaceAsync();

                    var status = await schemaManager.GetStatusAsync();

                    Assert.True(status.IsCurrent);
                }
            }

            // Create a new schema manager with upgrade scripts and ensure that
            // the updates are applied.

            scripts =
                new string[]
            {
                "CREATE KEYSPACE ${keyspace};",
                @"CREATE TABLE my_table (key integer, version integer, PRIMARY KEY (key));
GO           
INSERT INTO my_table (key, version) values (1, 1);",
                "UPDATE my_table SET version = 2 WHERE key = 1;",
                "UPDATE my_table SET version = 3 WHERE key = 1;",
                "UPDATE my_table SET version = 4 WHERE key = 1;",
            };

            using (var tempFolder = await PersistSchemaScriptsAsync(scripts))
            {
                using (var schemaManager = new SchemaManager(cassandra, keyspaceName, tempFolder.Path))
                {
                    var status = await schemaManager.GetStatusAsync();

                    Assert.Equal(SchemaStatus.ExistsWithSchema, status.SchemaStatus);
                    Assert.Equal(0, status.Version);
                    Assert.Equal(4, status.MaxVersion);
                    Assert.Equal(4, await schemaManager.UpgradeKeyspaceAsync());

                    // Verify that the updates were actually applied.

                    await ExecuteWithKeyspaceAsync(keyspaceName,
                                                   async() =>
                    {
                        var row = (await cassandra.ExecuteAsync("SELECT version FROM my_table WHERE key = 1;")).Single();

                        Assert.Equal(4, row.GetValue <int>("version"));
                    });
                }
            }

            // Add a modify the upgrade scripts to set differnt values and then
            // verify that the scripts weren't executed again during an upgrade.

            scripts =
                new string[]
            {
                "CREATE KEYSPACE ${keyspace};",
                @"CREATE TABLE my_table (key integer, version integer, PRIMARY KEY (key));
GO           
INSERT INTO my_table (key, version) values (1, 101);",
                "UPDATE my_table SET version = 102 WHERE key = 1;",
                "UPDATE my_table SET version = 103 WHERE key = 1;",
                "UPDATE my_table SET version = 104 WHERE key = 1;",
            };

            using (var tempFolder = await PersistSchemaScriptsAsync(scripts))
            {
                using (var schemaManager = new SchemaManager(cassandra, keyspaceName, tempFolder.Path))
                {
                    var status = await schemaManager.GetStatusAsync();

                    Assert.Equal(SchemaStatus.ExistsWithSchema, status.SchemaStatus);
                    Assert.Equal(4, status.Version);
                    Assert.Equal(4, status.MaxVersion);
                    Assert.Equal(4, await schemaManager.UpgradeKeyspaceAsync());

                    // Verify that the updates were not applied.

                    await ExecuteWithKeyspaceAsync(keyspaceName,
                                                   async() =>
                    {
                        var row = (await cassandra.ExecuteAsync("SELECT version FROM my_table WHERE key = 1;")).Single();

                        Assert.Equal(4, row.GetValue <int>("version"));
                    });
                }
            }
        }
Esempio n. 12
0
        public async Task Create_KeyspaceExists_NoDBInfo()
        {
            // Verify that create throws an exception when the keyspace already
            // exists but doesn't have a valid DBINFO table.

            var keyspaceName = GetUniqueKeyspaceName();
            var scripts      = new string[]
            {
                "CREATE KEYSPACE ${keyspace};"
            };

            await cassandra.ExecuteAsync($"CREATE KEYSPACE {keyspaceName};");

            using (var tempFolder = await PersistSchemaScriptsAsync(scripts))
            {
                using (var schemaManager = new SchemaManager(cassandra, keyspaceName, tempFolder.Path))
                {
                    var status = await schemaManager.GetStatusAsync();

                    Assert.Equal(SchemaStatus.ExistsNoSchema, status.SchemaStatus);
                    Assert.Equal(-1, status.Version);
                    Assert.Equal(0, status.MaxVersion);
                    Assert.False(status.IsCurrent);

                    await Assert.ThrowsAsync <SchemaManagerException>(async() => await schemaManager.CreateKeyspaceAsync());
                }
            }
        }