File 1163-Add-testcase-for-issue-8045.patch of Package erlang

From e916c3e01efc5a398f2aef0439ce0c0d443159c3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Micha=C5=82=20W=C4=85sowski?= <michal@erlang.org>
Date: Mon, 16 Dec 2024 18:24:30 +0100
Subject: [PATCH 3/3] Add testcase for issue-8045

---
 lib/mnesia/test/mnesia.spec                   |   3 +
 .../test/mnesia_external_backend_test.erl     | 156 ++++++++++++++----
 2 files changed, 129 insertions(+), 30 deletions(-)

diff --git a/lib/mnesia/test/mnesia.spec b/lib/mnesia/test/mnesia.spec
index e4746fe14c..39a40d4c7a 100644
--- a/lib/mnesia/test/mnesia.spec
+++ b/lib/mnesia/test/mnesia.spec
@@ -71,3 +71,6 @@
 {skip_cases,"../mnesia_test",mnesia_consistency_test,
             [consistency_after_rename_of_node],
             "Not yet implemented"}.
+{skip_cases,"../mnesia_test",mnesia_external_backend_test,
+            [backup_and_restore_should_work_with_external_backend],
+            "Not yet implemented"}.
diff --git a/lib/mnesia/test/mnesia_external_backend_test.erl b/lib/mnesia/test/mnesia_external_backend_test.erl
index 1391be7c88..0fcb075ea8 100644
--- a/lib/mnesia/test/mnesia_external_backend_test.erl
+++ b/lib/mnesia/test/mnesia_external_backend_test.erl
@@ -1,27 +1,52 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 1996-2024. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%%     http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%
+%% %CopyrightEnd%
+%%
+
 -module(mnesia_external_backend_test).
 
 -export([init_per_testcase/2, end_per_testcase/2,
          init_per_group/2, end_per_group/2,
          suite/0, all/0, groups/0]).
 
--export([conversion_from_external_to_disc_copies_results_in_data_loss_after_node_restart/1]).
+-export([
+    conversion_from_external_to_disc_copies_should_not_result_in_data_loss_after_node_restart/1,
+    backup_and_restore_should_work_with_external_backend/1,
+    schema_creation_should_work_when_external_tables_exist/1
+]).
 
 -include("mnesia_test_lib.hrl").
 
 -record(some_rec, {some_id :: atom(), some_int :: number(), some_string :: string()}).
 
--define(acquire(N, Config),
-        mnesia_test_lib:prepare_test_case([{init_test_case, [mnesia]},
-                                           delete_schema],
-                                          N, Config, ?FILE, ?LINE)).
-
-all() -> 
-    [conversion_from_external_to_disc_copies_results_in_data_loss_after_node_restart].
+all() -> [
+    conversion_from_external_to_disc_copies_should_not_result_in_data_loss_after_node_restart,
+    backup_and_restore_should_work_with_external_backend,
+    schema_creation_should_work_when_external_tables_exist
+].
 
 groups() ->
     [].
 
 init_per_testcase(Func, Conf) ->
+    file:delete("bup0.BUP"),
+    file:delete("bup1.BUP"),
+    file:delete("bup2.BUP"),
     mnesia_test_lib:init_per_testcase(Func, Conf).
 
 end_per_testcase(Func, Conf) ->
@@ -35,8 +60,7 @@ end_per_group(_GroupName, Config) ->
 
 suite() -> [{ct_hooks,[{ts_install_cth,[{nodenames,1}]}]}].
 
-conversion_from_external_to_disc_copies_results_in_data_loss_after_node_restart(Config) when is_list(Config) ->
-    Node = node(),
+conversion_from_external_to_disc_copies_should_not_result_in_data_loss_after_node_restart(Config) when is_list(Config) ->
     Data = [
         #some_rec{some_id = a, some_int = 1, some_string = "something" },
         #some_rec{some_id = b, some_int = 2, some_string = "anything"  },
@@ -44,36 +68,108 @@ conversion_from_external_to_disc_copies_results_in_data_loss_after_node_restart(
         #some_rec{some_id = d, some_int = 4, some_string = "nothing"   }
     ],
 
-    [Node] = ?acquire(1, Config),
-    ok = mnesia:create_schema([Node]),
-    ok = mnesia:start(),
-    {atomic, ok} = mnesia:add_backend_type(ext_ets, ext_test),
-    {atomic, ok} = mnesia:add_backend_type(ext_dets, ext_test),
-    {atomic, ok} = mnesia:create_table(table, [
+    [Node] = ?acquire_nodes(1, Config),
+    ?match({atomic, ok}, mnesia:create_table(table, [
         {type, ordered_set},
         {record_name, some_rec},
         {attributes, record_info(fields, some_rec)},
         {disc_copies, [Node]}
-    ]),
+    ])),
 
-    ok = mnesia:activity(transaction, fun() ->
+    ?match(ok, mnesia:activity(transaction, fun() ->
         lists:foreach(fun(Elem) -> mnesia:write(table, Elem, write) end, Data)
-    end),
+    end)),
 
-    {atomic, ok} = mnesia:change_table_copy_type(table, Node, ext_ets),
-    Data = mnesia:activity(transaction, fun() ->
+    ?match({atomic, ok}, mnesia:change_table_copy_type(table, Node, ext_ram_copies)),
+    ?match(Data, mnesia:activity(transaction, fun() ->
         mnesia:match_object(table, #some_rec{_ = '_'}, read) end
-    ),
+    )),
 
-    {atomic, ok} = mnesia:change_table_copy_type(table, Node, disc_copies),
-    Data = mnesia:activity(transaction, fun() ->
+    ?match({atomic, ok}, mnesia:change_table_copy_type(table, Node, disc_copies)),
+    ?match(Data, mnesia:activity(transaction, fun() ->
         mnesia:match_object(table, #some_rec{_ = '_'}, read) end
-    ),
+    )),
 
-    stopped = mnesia:stop(),
-    ok = mnesia:start(),
-    ok = mnesia:wait_for_tables([schema, table], 10000),
+    ?match(stopped, mnesia:stop()),
+    ?match(ok, mnesia:start()),
+    ?match(ok, mnesia:wait_for_tables([schema, table], 10000)),
 
-    Data = mnesia:activity(transaction, fun() ->
+    ?match(Data, mnesia:activity(transaction, fun() ->
         mnesia:match_object(table, #some_rec{_ = '_'}, read) end
-    ).
+    )),
+
+    ?verify_mnesia([Node], []).
+
+backup_and_restore_should_work_with_external_backend(Config) when is_list(Config) ->
+    Data1 = [
+        #some_rec{some_id = a, some_int = 1, some_string = "1"},
+        #some_rec{some_id = b, some_int = 2, some_string = "2"},
+        #some_rec{some_id = c, some_int = 3, some_string = "3"}
+    ],
+    Data2 = [
+        #some_rec{some_id = d, some_int = 4, some_string = "4"},
+        #some_rec{some_id = e, some_int = 5, some_string = "5"},
+        #some_rec{some_id = f, some_int = 6, some_string = "6"}
+    ],
+
+    [Node] = ?acquire_nodes(1, Config),
+    ?match({atomic, ok}, mnesia:create_table(table, [
+        {type, set},
+        {record_name, some_rec},
+        {attributes, record_info(fields, some_rec)},
+        {ext_disc_only_copies, [Node]}
+    ])),
+
+    ?match({atomic, ok}, mnesia:add_table_index(table, #some_rec.some_int)),
+    ?match([], mnesia:dirty_match_object(table, #some_rec{_ = '_'})),
+    ?match(ok, mnesia:backup("bup0.BUP")),
+
+    ?match(ok, mnesia:activity(transaction, fun() ->
+        lists:foreach(fun(Elem) -> mnesia:write(table, Elem, write) end, Data1)
+    end)),
+    ?match(ok, mnesia:backup("bup1.BUP")),
+
+    ?match(ok, mnesia:activity(transaction, fun() ->
+        lists:foreach(fun(Elem) -> mnesia:write(table, Elem, write) end, Data2)
+    end)),
+    ?match(ok, mnesia:backup("bup2.BUP")),
+
+    ?match(ok, load_backup("bup0.BUP")),
+    ?match([], mnesia:dirty_match_object(table, #some_rec{_ = '_'})),
+    ?match([], mnesia:dirty_index_read(table, 2, #some_rec.some_int)),
+
+    ?match(ok, load_backup("bup1.BUP")),
+    Expected1 = sets:from_list(Data1),
+    ?match(Expected1, sets:from_list(mnesia:dirty_match_object(table, #some_rec{_ = '_'}))),
+    ?match([#some_rec{some_id = b, some_int = 2, some_string = "2"}], mnesia:dirty_index_read(table, 2, #some_rec.some_int)),
+
+    ?match(ok, load_backup("bup2.BUP")),
+    Expected2 = sets:from_list(lists:append(Data1, Data2)),
+    ?match(Expected2, sets:from_list(mnesia:dirty_match_object(table, #some_rec{_ = '_'}))),
+    ?match([#some_rec{some_id = b, some_int = 2, some_string = "2"}], mnesia:dirty_index_read(table, 2, #some_rec.some_int)),
+    ?match([#some_rec{some_id = e, some_int = 5, some_string = "5"}], mnesia:dirty_index_read(table, 5, #some_rec.some_int)),
+
+    ?verify_mnesia([Node], []).
+
+schema_creation_should_work_when_external_tables_exist(Config) when is_list(Config) ->
+    [Node] = ?acquire_nodes(1, Config),
+    ?match({atomic, ok}, mnesia:create_table(table, [
+        {type, set},
+        {record_name, some_rec},
+        {attributes, record_info(fields, some_rec)},
+        {ext_disc_only_copies, [Node]}
+    ])),
+    
+    ?match(stopped, mnesia:stop()),
+    ?match(ok, mnesia:delete_schema([Node])),
+
+    Ext = proplists:get_value(default_properties, Config, ?BACKEND),
+    ?match(ok, mnesia:create_schema([Node], Ext)).
+
+load_backup(BUP) ->
+    ?match(ok, mnesia:install_fallback(BUP)),
+    ?match(stopped, mnesia:stop()),
+    timer:sleep(3000),
+    ?match(ok, mnesia:start()),
+    ?match(ok, mnesia:wait_for_tables([schema, table], 5000)),
+    ok.
-- 
2.43.0

openSUSE Build Service is sponsored by