|
| 1 | +#include <util/system/env.h> |
| 2 | +#include <library/cpp/testing/unittest/registar.h> |
| 3 | + |
| 4 | +#include <ydb/library/testlib/s3_recipe_helper/s3_recipe_helper.h> |
| 5 | + |
| 6 | +#include <ydb/public/sdk/cpp/client/ydb_driver/driver.h> |
| 7 | +#include <ydb/public/sdk/cpp/client/ydb_export/export.h> |
| 8 | +#include <ydb/public/sdk/cpp/client/ydb_import/import.h> |
| 9 | +#include <ydb/public/sdk/cpp/client/ydb_operation/operation.h> |
| 10 | +#include <ydb/public/sdk/cpp/client/ydb_table/table.h> |
| 11 | +#include <ydb/public/sdk/cpp/client/draft/ydb_scripting.h> |
| 12 | +#include <ydb/public/lib/yson_value/ydb_yson_value.h> |
| 13 | +#include <library/cpp/yson/writer.h> |
| 14 | + |
| 15 | +#include <library/cpp/threading/local_executor/local_executor.h> |
| 16 | + |
| 17 | +using namespace NYdb; |
| 18 | +using namespace NYdb::NTable; |
| 19 | + |
| 20 | +namespace { |
| 21 | + template<typename TOp> |
| 22 | + void WaitOp(TMaybe<TOperation>& op, NOperation::TOperationClient& opClient) { |
| 23 | + int attempt = 20; |
| 24 | + while (--attempt) { |
| 25 | + op = opClient.Get<TOp>(op->Id()).GetValueSync(); |
| 26 | + if (op->Ready()) { |
| 27 | + break; |
| 28 | + } |
| 29 | + Sleep(TDuration::Seconds(1)); |
| 30 | + } |
| 31 | + UNIT_ASSERT_C(attempt, "Unable to wait completion of backup"); |
| 32 | + } |
| 33 | + |
| 34 | + TString ReformatYson(const TString& yson) { |
| 35 | + TStringStream ysonInput(yson); |
| 36 | + TStringStream output; |
| 37 | + NYson::ReformatYsonStream(&ysonInput, &output, NYson::EYsonFormat::Text); |
| 38 | + return output.Str(); |
| 39 | + } |
| 40 | + |
| 41 | + void CompareYson(const TString& expected, const TString& actual) { |
| 42 | + UNIT_ASSERT_NO_DIFF(ReformatYson(expected), ReformatYson(actual)); |
| 43 | + } |
| 44 | +} |
| 45 | + |
| 46 | +Y_UNIT_TEST_SUITE(Backup) |
| 47 | +{ |
| 48 | + Y_UNIT_TEST(UuidValue) |
| 49 | + { |
| 50 | + TString connectionString = GetEnv("YDB_ENDPOINT") + "/?database=" + GetEnv("YDB_DATABASE"); |
| 51 | + auto config = TDriverConfig(connectionString); |
| 52 | + auto driver = TDriver(config); |
| 53 | + auto tableClient = TTableClient(driver); |
| 54 | + auto session = tableClient.GetSession().GetValueSync().GetSession(); |
| 55 | + |
| 56 | + { |
| 57 | + auto res = session.ExecuteSchemeQuery(R"( |
| 58 | + CREATE TABLE `/local/ProducerUuidValue` ( |
| 59 | + Key Uint32, |
| 60 | + Value1 Uuid, |
| 61 | + Value2 Uuid NOT NULL, |
| 62 | + PRIMARY KEY (Key) |
| 63 | + ); |
| 64 | + )").GetValueSync(); |
| 65 | + UNIT_ASSERT_C(res.IsSuccess(), res.GetIssues().ToString()); |
| 66 | + } |
| 67 | + |
| 68 | + { |
| 69 | + auto sessionResult = tableClient.GetSession().GetValueSync(); |
| 70 | + UNIT_ASSERT_C(sessionResult.IsSuccess(), sessionResult.GetIssues().ToString()); |
| 71 | + auto s = sessionResult.GetSession(); |
| 72 | + |
| 73 | + { |
| 74 | + const TString query = "UPSERT INTO ProducerUuidValue (Key, Value1, Value2) VALUES" |
| 75 | + "(1, " |
| 76 | + "CAST(\"5b99a330-04ef-4f1a-9b64-ba6d5f44ea01\" as Uuid), " |
| 77 | + "UNWRAP(CAST(\"5b99a330-04ef-4f1a-9b64-ba6d5f44ea02\" as Uuid)" |
| 78 | + "));"; |
| 79 | + auto res = s.ExecuteDataQuery(query, TTxControl::BeginTx().CommitTx()).GetValueSync(); |
| 80 | + UNIT_ASSERT_C(res.IsSuccess(), res.GetIssues().ToString()); |
| 81 | + } |
| 82 | + } |
| 83 | + |
| 84 | + const TString bucketName = "bbb"; |
| 85 | + NTestUtils::CreateBucket(bucketName); |
| 86 | + |
| 87 | + auto fillS3Settings = [bucketName](auto& settings) { |
| 88 | + settings.Endpoint(GetEnv("S3_ENDPOINT")); |
| 89 | + settings.Bucket(bucketName); |
| 90 | + settings.AccessKey("minio"); |
| 91 | + settings.SecretKey("minio123"); |
| 92 | + }; |
| 93 | + |
| 94 | + { |
| 95 | + NExport::TExportToS3Settings settings; |
| 96 | + fillS3Settings(settings); |
| 97 | + |
| 98 | + settings.AppendItem({"/local/ProducerUuidValue", "ProducerUuidValueBackup"}); |
| 99 | + |
| 100 | + auto exportClient = NExport::TExportClient(driver); |
| 101 | + auto operationClient = NOperation::TOperationClient(driver); |
| 102 | + |
| 103 | + const auto backupOp = exportClient.ExportToS3(settings).GetValueSync(); |
| 104 | + |
| 105 | + if (backupOp.Ready()) { |
| 106 | + UNIT_ASSERT_C(backupOp.Status().IsSuccess(), backupOp.Status().GetIssues().ToString()); |
| 107 | + } else { |
| 108 | + TMaybe<TOperation> op = backupOp; |
| 109 | + WaitOp<NExport::TExportToS3Response>(op, operationClient); |
| 110 | + UNIT_ASSERT_C(op->Status().IsSuccess(), op->Status().GetIssues().ToString()); |
| 111 | + } |
| 112 | + } |
| 113 | + |
| 114 | + auto ob = NTestUtils::GetObjectKeys(bucketName); |
| 115 | + std::sort(ob.begin(), ob.end()); |
| 116 | + UNIT_ASSERT_VALUES_EQUAL(ob.size(), 3); |
| 117 | + UNIT_ASSERT_VALUES_EQUAL(ob[0], "ProducerUuidValueBackup/data_00.csv"); |
| 118 | + UNIT_ASSERT_VALUES_EQUAL(ob[1], "ProducerUuidValueBackup/metadata.json"); |
| 119 | + UNIT_ASSERT_VALUES_EQUAL(ob[2], "ProducerUuidValueBackup/scheme.pb"); |
| 120 | + |
| 121 | + { |
| 122 | + NImport::TImportFromS3Settings settings; |
| 123 | + fillS3Settings(settings); |
| 124 | + |
| 125 | + settings.AppendItem({"ProducerUuidValueBackup", "/local/restore"}); |
| 126 | + |
| 127 | + auto importClient = NImport::TImportClient(driver); |
| 128 | + auto operationClient = NOperation::TOperationClient(driver); |
| 129 | + |
| 130 | + const auto restoreOp = importClient.ImportFromS3(settings).GetValueSync(); |
| 131 | + |
| 132 | + if (restoreOp.Ready()) { |
| 133 | + UNIT_ASSERT_C(restoreOp.Status().IsSuccess(), restoreOp.Status().GetIssues().ToString()); |
| 134 | + } else { |
| 135 | + TMaybe<TOperation> op = restoreOp; |
| 136 | + WaitOp<NImport::TImportFromS3Response>(op, operationClient); |
| 137 | + UNIT_ASSERT_C(op->Status().IsSuccess(), op->Status().GetIssues().ToString()); |
| 138 | + } |
| 139 | + } |
| 140 | + |
| 141 | + { |
| 142 | + auto sessionResult = tableClient.GetSession().GetValueSync(); |
| 143 | + UNIT_ASSERT_C(sessionResult.IsSuccess(), sessionResult.GetIssues().ToString()); |
| 144 | + auto s = sessionResult.GetSession(); |
| 145 | + |
| 146 | + { |
| 147 | + const TString query = "SELECT * FROM `/local/restore`;"; |
| 148 | + auto res = s.ExecuteDataQuery(query, TTxControl::BeginTx().CommitTx()).GetValueSync(); |
| 149 | + UNIT_ASSERT_C(res.IsSuccess(), res.GetIssues().ToString()); |
| 150 | + |
| 151 | + auto yson = NYdb::FormatResultSetYson(res.GetResultSet(0)); |
| 152 | + |
| 153 | + const TString& expected = "[[[1u];[\"5b99a330-04ef-4f1a-9b64-ba6d5f44ea01\"];\"5b99a330-04ef-4f1a-9b64-ba6d5f44ea02\"]]"; |
| 154 | + CompareYson(expected, yson); |
| 155 | + } |
| 156 | + } |
| 157 | + } |
| 158 | +} |
| 159 | + |
0 commit comments