@@ -1503,4 +1503,162 @@ partitioning_settings {
15031503 TestGetExport (runtime, exportId, " /MyRoot" );
15041504 env.TestWaitNotification (runtime, exportId);
15051505 }
1506+
1507+ Y_UNIT_TEST (ExportStartTime) {
1508+ TTestBasicRuntime runtime;
1509+ TTestEnv env (runtime);
1510+ ui64 txId = 100 ;
1511+
1512+ TestCreateTable (runtime, ++txId, " /MyRoot" , R"(
1513+ Name: "Table"
1514+ Columns { Name: "key" Type: "Utf8" }
1515+ Columns { Name: "value" Type: "Utf8" }
1516+ KeyColumnNames: ["key"]
1517+ )" );
1518+ env.TestWaitNotification (runtime, txId);
1519+
1520+ TPortManager portManager;
1521+ const ui16 port = portManager.GetPort ();
1522+
1523+ TS3Mock s3Mock ({}, TS3Mock::TSettings (port));
1524+ UNIT_ASSERT (s3Mock.Start ());
1525+
1526+ TestExport (runtime, ++txId, " /MyRoot" , Sprintf (R"(
1527+ ExportToS3Settings {
1528+ endpoint: "localhost:%d"
1529+ scheme: HTTP
1530+ items {
1531+ source_path: "/MyRoot/Table"
1532+ destination_prefix: ""
1533+ }
1534+ }
1535+ )" , port));
1536+
1537+ const auto desc = TestGetExport (runtime, txId, " /MyRoot" );
1538+ const auto & entry = desc.GetResponse ().GetEntry ();
1539+ UNIT_ASSERT_VALUES_EQUAL (entry.GetProgress (), Ydb::Export::ExportProgress::PROGRESS_PREPARING);
1540+ UNIT_ASSERT (entry.HasStartTime ());
1541+ UNIT_ASSERT (!entry.HasEndTime ());
1542+ }
1543+
1544+ Y_UNIT_TEST (CompletedExportEndTime) {
1545+ TTestBasicRuntime runtime;
1546+ TTestEnv env (runtime);
1547+ ui64 txId = 100 ;
1548+
1549+ TestCreateTable (runtime, ++txId, " /MyRoot" , R"(
1550+ Name: "Table"
1551+ Columns { Name: "key" Type: "Utf8" }
1552+ Columns { Name: "value" Type: "Utf8" }
1553+ KeyColumnNames: ["key"]
1554+ )" );
1555+ env.TestWaitNotification (runtime, txId);
1556+
1557+ TPortManager portManager;
1558+ const ui16 port = portManager.GetPort ();
1559+
1560+ TS3Mock s3Mock ({}, TS3Mock::TSettings (port));
1561+ UNIT_ASSERT (s3Mock.Start ());
1562+
1563+ TestExport (runtime, ++txId, " /MyRoot" , Sprintf (R"(
1564+ ExportToS3Settings {
1565+ endpoint: "localhost:%d"
1566+ scheme: HTTP
1567+ items {
1568+ source_path: "/MyRoot/Table"
1569+ destination_prefix: ""
1570+ }
1571+ }
1572+ )" , port));
1573+
1574+ runtime.AdvanceCurrentTime (TDuration::Seconds (30 )); // doing backup
1575+
1576+ env.TestWaitNotification (runtime, txId);
1577+
1578+ const auto desc = TestGetExport (runtime, txId, " /MyRoot" );
1579+ const auto & entry = desc.GetResponse ().GetEntry ();
1580+ UNIT_ASSERT_VALUES_EQUAL (entry.GetProgress (), Ydb::Export::ExportProgress::PROGRESS_DONE);
1581+ UNIT_ASSERT (entry.HasStartTime ());
1582+ UNIT_ASSERT (entry.HasEndTime ());
1583+ UNIT_ASSERT_LT (entry.GetStartTime ().seconds (), entry.GetEndTime ().seconds ());
1584+ }
1585+
1586+ Y_UNIT_TEST (CancelledExportEndTime) {
1587+ TTestBasicRuntime runtime;
1588+ TTestEnv env (runtime);
1589+ ui64 txId = 100 ;
1590+
1591+ TestCreateTable (runtime, ++txId, " /MyRoot" , R"(
1592+ Name: "Table"
1593+ Columns { Name: "key" Type: "Utf8" }
1594+ Columns { Name: "value" Type: "Utf8" }
1595+ KeyColumnNames: ["key"]
1596+ )" );
1597+ env.TestWaitNotification (runtime, txId);
1598+
1599+ auto delayFunc = [](TAutoPtr<IEventHandle>& ev) {
1600+ if (ev->GetTypeRewrite () != TEvSchemeShard::EvModifySchemeTransaction) {
1601+ return false ;
1602+ }
1603+
1604+ return ev->Get <TEvSchemeShard::TEvModifySchemeTransaction>()->Record
1605+ .GetTransaction (0 ).GetOperationType () == NKikimrSchemeOp::ESchemeOpBackup;
1606+ };
1607+
1608+ THolder<IEventHandle> delayed;
1609+ auto prevObserver = runtime.SetObserverFunc ([&](TAutoPtr<IEventHandle>& ev) {
1610+ if (delayFunc (ev)) {
1611+ delayed.Reset (ev.Release ());
1612+ return TTestActorRuntime::EEventAction::DROP;
1613+ }
1614+ return TTestActorRuntime::EEventAction::PROCESS;
1615+ });
1616+
1617+ TPortManager portManager;
1618+ const ui16 port = portManager.GetPort ();
1619+
1620+ TS3Mock s3Mock ({}, TS3Mock::TSettings (port));
1621+ UNIT_ASSERT (s3Mock.Start ());
1622+
1623+ TestExport (runtime, ++txId, " /MyRoot" , Sprintf (R"(
1624+ ExportToS3Settings {
1625+ endpoint: "localhost:%d"
1626+ scheme: HTTP
1627+ items {
1628+ source_path: "/MyRoot/Table"
1629+ destination_prefix: ""
1630+ }
1631+ }
1632+ )" , port));
1633+ const ui64 exportId = txId;
1634+
1635+ runtime.AdvanceCurrentTime (TDuration::Seconds (30 )); // doing backup
1636+
1637+ if (!delayed) {
1638+ TDispatchOptions opts;
1639+ opts.FinalEvents .emplace_back ([&delayed](IEventHandle&) -> bool {
1640+ return bool (delayed);
1641+ });
1642+ runtime.DispatchEvents (opts);
1643+ }
1644+ runtime.SetObserverFunc (prevObserver);
1645+
1646+ TestCancelExport (runtime, ++txId, " /MyRoot" , exportId);
1647+
1648+ auto desc = TestGetExport (runtime, exportId, " /MyRoot" );
1649+ auto entry = desc.GetResponse ().GetEntry ();
1650+ UNIT_ASSERT_VALUES_EQUAL (entry.GetProgress (), Ydb::Export::ExportProgress::PROGRESS_CANCELLATION);
1651+ UNIT_ASSERT (entry.HasStartTime ());
1652+ UNIT_ASSERT (!entry.HasEndTime ());
1653+
1654+ runtime.Send (delayed.Release (), 0 , true );
1655+ env.TestWaitNotification (runtime, exportId);
1656+
1657+ desc = TestGetExport (runtime, exportId, " /MyRoot" , Ydb::StatusIds::CANCELLED);
1658+ entry = desc.GetResponse ().GetEntry ();
1659+ UNIT_ASSERT_VALUES_EQUAL (entry.GetProgress (), Ydb::Export::ExportProgress::PROGRESS_CANCELLED);
1660+ UNIT_ASSERT (entry.HasStartTime ());
1661+ UNIT_ASSERT (entry.HasEndTime ());
1662+ UNIT_ASSERT_LT (entry.GetStartTime ().seconds (), entry.GetEndTime ().seconds ());
1663+ }
15061664}
0 commit comments