gem5 v24.0.0.0
Loading...
Searching...
No Matches
serialize.test.cc
Go to the documentation of this file.
1/*
2 * Copyright 2021 Daniel R. Carvalho
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met: redistributions of source code must retain the above copyright
7 * notice, this list of conditions and the following disclaimer;
8 * redistributions in binary form must reproduce the above copyright
9 * notice, this list of conditions and the following disclaimer in the
10 * documentation and/or other materials provided with the distribution;
11 * neither the name of the copyright holders nor the names of its
12 * contributors may be used to endorse or promote products derived from
13 * this software without specific prior written permission.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
19 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
21 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28#include <gmock/gmock.h>
29#include <gtest/gtest-spi.h>
30#include <gtest/gtest.h>
31#include <sys/stat.h>
32#include <sys/types.h>
33#include <unistd.h>
34
35#include <array>
36#include <cassert>
37#include <cstdint>
38#include <deque>
39#include <fstream>
40#include <list>
41#include <memory>
42#include <set>
43#include <string>
44#include <vector>
45
46#include "base/compiler.hh"
48#include "base/gtest/logging.hh"
50#include "sim/serialize.hh"
51
52using namespace gem5;
53
54// Instantiate the mock class to have a valid curTick of 0
56
58bool
59dirExists(std::string dir)
60{
61 struct stat info;
62 return (stat(dir.c_str(), &info) == 0) && (info.st_mode & S_IFDIR);
63}
64
66
68{
69 public:
70 std::unique_ptr<CheckpointIn> cpt;
71
72 using SerializeFixture::SerializeFixture;
73
74 void
75 SetUp() override
76 {
78
79 std::ofstream file(getCptPath());
80 assert(file.good());
81 file << R"cpt_file(
82[General]
83 Test1=BARasdf
84 Test2=bar
85
86[Junk]
87Test3=yo
88Test4=mama
89
90[Foo]
91Foo1=89
92Foo2=384
93
94[General]
95Test3=89
96
97[Junk]
98Test4+=mia
99)cpt_file";
100 file.close();
101 cpt = std::make_unique<CheckpointIn>(getDirName());
102 }
103
104 void
105 TearDown() override
106 {
107 std::remove((getCptPath()).c_str());
109 }
110};
111
117{
118 public:
119 std::unique_ptr<CheckpointIn> cpt_in;
120 std::unique_ptr<std::ofstream> cpt_out;
121
122 using SerializeFixture::SerializeFixture;
123
124 void
125 SetUp() override
126 {
128
129 cpt_out = std::make_unique<std::ofstream>(getCptPath());
130 assert(cpt_out->good());
131 cpt_in = std::make_unique<CheckpointIn>(getDirName());
132 }
133
134 void
135 TearDown() override
136 {
137 std::remove((getCptPath()).c_str());
139 }
140};
141
145
147TEST(CheckpointInTest, SetGetDirSlash)
148{
149 ASSERT_EQ(CheckpointIn::setDir(""), "/");
150 ASSERT_EQ(CheckpointIn::dir(), "/");
151 ASSERT_EQ(CheckpointIn::setDir("/"), "/");
152 ASSERT_EQ(CheckpointIn::dir(), "/");
153 ASSERT_EQ(CheckpointIn::setDir("test_cpt_dir"), "test_cpt_dir/");
154 ASSERT_EQ(CheckpointIn::dir(), "test_cpt_dir/");
155 ASSERT_EQ(CheckpointIn::setDir("test_cpt_dir_2/"), "test_cpt_dir_2/");
156 ASSERT_EQ(CheckpointIn::dir(), "test_cpt_dir_2/");
157}
158
163TEST(CheckpointInTest, SetGetDirTick)
164{
165 ASSERT_EQ(CheckpointIn::setDir("tick%d"), "tick0/");
166 ASSERT_EQ(CheckpointIn::dir(), "tick0/");
167 ASSERT_EQ(CheckpointIn::setDir("ti%dck"), "ti0ck/");
168 ASSERT_EQ(CheckpointIn::dir(), "ti0ck/");
169}
170
176{
177 // Assign another cpt dir to make sure that it is changed when a new
178 // CheckpointIn instance is created
179 CheckpointIn::setDir("test");
180
181 // Make sure file does not exist, so that the constructor will fail
182 std::ifstream file(getCptPath());
183 assert(!file.good());
184 ASSERT_ANY_THROW(CheckpointIn cpt(getDirName()));
185}
186
191TEST_F(SerializeFixture, ConstructorSuccess)
192{
193 // Assign another cpt dir to make sure that it is changed when a new
194 // CheckpointIn instance is created
195 CheckpointIn::setDir("test");
196
197 // Create the file before creating the cpt to make sure it exists
198 std::ofstream file(getCptPath());
199 assert(file.good());
200 file.close();
201 CheckpointIn cpt(getDirName());
202
203 // When a new CheckpointIn instance is created the static cpt dir changes
204 EXPECT_EQ(CheckpointIn::dir(), getDirName());
205}
206
212{
213 ASSERT_ANY_THROW(CheckpointIn("/random_dir_name"));
214}
215
218{
219 // Successful searches
220 ASSERT_TRUE(cpt->sectionExists("General"));
221 ASSERT_TRUE(cpt->sectionExists("Junk"));
222 ASSERT_TRUE(cpt->sectionExists("Foo"));
223
224 // Failed searches
225 ASSERT_FALSE(cpt->sectionExists("Junk2"));
226 ASSERT_FALSE(cpt->sectionExists("Test1"));
227}
228
231{
232 // Successful searches
233 ASSERT_TRUE(cpt->entryExists("General", "Test2"));
234 ASSERT_TRUE(cpt->entryExists("Junk", "Test3"));
235 ASSERT_TRUE(cpt->entryExists("Junk", "Test4"));
236 ASSERT_TRUE(cpt->entryExists("General", "Test1"));
237 ASSERT_TRUE(cpt->entryExists("General", "Test3"));
238
239 // Failed searches
240 ASSERT_FALSE(cpt->entryExists("Junk2", "test3"));
241 ASSERT_FALSE(cpt->entryExists("Junk", "test4"));
242}
243
246{
247 std::string value;
248
249 // Successful searches
250 ASSERT_TRUE(cpt->find("General", "Test2", value));
251 ASSERT_EQ(value, "bar");
252 ASSERT_TRUE(cpt->find("Junk", "Test3", value));
253 ASSERT_EQ(value, "yo");
254 ASSERT_TRUE(cpt->find("Junk", "Test4", value));
255 ASSERT_EQ(value, "mama mia");
256 ASSERT_TRUE(cpt->find("General", "Test1", value));
257 ASSERT_EQ(value, "BARasdf");
258 ASSERT_TRUE(cpt->find("General", "Test3", value));
259 ASSERT_EQ(value, "89");
260
261 // Failed searches
262 ASSERT_FALSE(cpt->find("Junk2", "test3", value));
263 ASSERT_FALSE(cpt->find("Junk", "test4", value));
264}
265
270TEST_F(CheckpointInFixture, SCSCptInPathScoped)
271{
272 Serializable::ScopedCheckpointSection scs(*(cpt.get()), "Section1");
273 ASSERT_EQ(Serializable::currentSection(), "Section1");
274
275 {
276 Serializable::ScopedCheckpointSection scs_2(*(cpt.get()), "Section2");
277 ASSERT_EQ(Serializable::currentSection(), "Section1.Section2");
278
279 Serializable::ScopedCheckpointSection scs_3(*(cpt.get()), "Section3");
281 "Section1.Section2.Section3");
282 }
283
284 Serializable::ScopedCheckpointSection scs_4(*(cpt.get()), "Section4");
285 ASSERT_EQ(Serializable::currentSection(), "Section1.Section4");
286}
287
292TEST_F(SerializeFixture, SCSCptOutPathScoped)
293{
294 std::ofstream cpt(getCptPath());
295
297 ASSERT_EQ(Serializable::currentSection(), "Section1");
298
299 {
300 Serializable::ScopedCheckpointSection scs_2(cpt, "Section2");
301 ASSERT_EQ(Serializable::currentSection(), "Section1.Section2");
302
303 Serializable::ScopedCheckpointSection scs_3(cpt, "Section3");
305 "Section1.Section2.Section3");
306 }
307
308 Serializable::ScopedCheckpointSection scs_4(cpt, "Section4");
309 ASSERT_EQ(Serializable::currentSection(), "Section1.Section4");
310}
311
316TEST_F(SerializeFixture, SCSNoChangeCptIn)
317{
318 {
319 // Create empty cpt file
320 std::ofstream os(getCptPath());
321 assert(os.good());
322 os.close();
323 }
324
325 CheckpointIn cpt(getDirName());
326
327 std::ifstream is(getCptPath());
328 assert(is.good());
329 ASSERT_EQ(is.peek(), std::ifstream::traits_type::eof());
330
332 ASSERT_EQ(is.peek(), std::ifstream::traits_type::eof());
333 ASSERT_EQ(Serializable::currentSection(), "Section1");
334}
335
337std::string
338getString(std::istream &is)
339{
340 auto buf = is.rdbuf();
341 std::ostringstream oss;
342 oss << buf;
343 return oss.str();
344}
345
353std::string
354getContents(std::ofstream &cpt, std::string filename)
355{
356 // The checkpoint must be flushed, otherwise the file may not be up-
357 // to-date and the assertions below will fail
358 cpt.flush();
359
360 std::ifstream is(filename);
361 assert(is.good());
362 return std::string(std::istreambuf_iterator<char>(is),
363 std::istreambuf_iterator<char>());
364}
365
370TEST_F(SerializableFixture, SCSChangeCptOutSingle)
371{
372 Serializable::ScopedCheckpointSection scs(*cpt_out, "Section1");
373 ASSERT_EQ(getContents(*cpt_out, getCptPath()),
374 "\n[Section1]\n");
375}
376
381TEST_F(SerializableFixture, SCSChangeCptOutMultiple)
382{
383 std::string expected = "";
384 Serializable::ScopedCheckpointSection scs(*cpt_out, "Section1");
385 expected += "\n[Section1]\n";
386 ASSERT_EQ(getContents(*cpt_out, getCptPath()), expected);
387
388 {
389 Serializable::ScopedCheckpointSection scs_2(*cpt_out, "Section2");
390 expected += "\n[Section1.Section2]\n";
391 ASSERT_EQ(getContents(*cpt_out, getCptPath()), expected);
392
393 Serializable::ScopedCheckpointSection scs_3(*cpt_out, "Section3");
394 expected += "\n[Section1.Section2.Section3]\n";
395 ASSERT_EQ(getContents(*cpt_out, getCptPath()), expected);
396 }
397
398 Serializable::ScopedCheckpointSection scs_4(*cpt_out, "Section4");
399 expected += "\n[Section1.Section4]\n";
400 ASSERT_EQ(getContents(*cpt_out, getCptPath()), expected);
401}
402
407TEST_F(SerializableFixture, SCSChangeCptOutLarge)
408{
409 std::string expected = "";
410 Serializable::ScopedCheckpointSection scs(*cpt_out, "Section1");
411 expected += "\n[Section1]\n";
412 ASSERT_EQ(getContents(*cpt_out, getCptPath()), expected);
413
414 {
415 Serializable::ScopedCheckpointSection scs_2(*cpt_out, "Section2");
416 expected += "\n[Section1.Section2]\n";
417 ASSERT_EQ(getContents(*cpt_out, getCptPath()), expected);
418
419 {
420 Serializable::ScopedCheckpointSection scs_3(*cpt_out, "Section3");
421 expected += "\n[Section1.Section2.Section3]\n";
422 ASSERT_EQ(getContents(*cpt_out, getCptPath()),
423 expected);
424 }
425
426 Serializable::ScopedCheckpointSection scs_4(*cpt_out, "Section4");
427 expected += "\n[Section1.Section2.Section4]\n";
428 ASSERT_EQ(getContents(*cpt_out, getCptPath()), expected);
429 }
430
431 Serializable::ScopedCheckpointSection scs_5(*cpt_out, "Section5");
432 expected += "\n[Section1.Section5]\n";
433 ASSERT_EQ(getContents(*cpt_out, getCptPath()), expected);
434
435 {
436 Serializable::ScopedCheckpointSection scs_6(*cpt_out, "Section6");
437 expected += "\n[Section1.Section5.Section6]\n";
438 ASSERT_EQ(getContents(*cpt_out, getCptPath()), expected);
439
440 Serializable::ScopedCheckpointSection scs_7(*cpt_out, "Section7");
441 expected += "\n[Section1.Section5.Section6.Section7]\n";
442 ASSERT_EQ(getContents(*cpt_out, getCptPath()), expected);
443 }
444
445 Serializable::ScopedCheckpointSection scs_8(*cpt_out, "Section8");
446 expected += "\n[Section1.Section5.Section8]\n";
447 ASSERT_EQ(getContents(*cpt_out, getCptPath()), expected);
448}
449
451TEST(SerializableDeathTest, GenerateCptOutFail)
452{
453 std::ofstream cpt;
454 const std::string dir_name =
456 ASSERT_FALSE(dirExists(dir_name));
457
459 dir_name + "/b/a/n/a/n/a/", cpt));
460}
461
463TEST_F(SerializeFixture, GenerateCptOut)
464{
465 // The fixture will auto-create the dir. Remove it.
466 assert(rmdir(getDirName().c_str()) == 0);
467
468 std::ofstream cpt;
469 Serializable::generateCheckpointOut(getDirName(), cpt);
470 ASSERT_TRUE(dirExists(getDirName()));
471
472 // Make sure the checkpoint was properly created. Using EXPECT to
473 // force removing the directory at the end
474 EXPECT_NE(getContents(cpt, getCptPath()).find(
475 "## checkpoint generated: "), std::string::npos);
476}
477
479TEST_F(SerializeFixture, GenerateCptOutExistent)
480{
481 assert(dirExists(getDirName()));
482
483 // Create the checkpoint and make sure it has been properly created by
484 // deleting it and making sure the function was successful
485 std::ofstream cpt;
486 Serializable::generateCheckpointOut(getDirName(), cpt);
487 EXPECT_TRUE(remove((getCptPath()).c_str()) == 0);
488}
489
491{
492 private:
493 mutable bool _serialized = false;
494 bool _unserialized = false;
495
496 public:
498
499 void serialize(CheckpointOut &cp) const override { _serialized = true; }
500 void unserialize(CheckpointIn &cp) override { _unserialized = true; }
501
507 bool
509 {
510 const bool serialized = _serialized;
511 _serialized = false;
512 return serialized;
513 }
514
520 bool
522 {
523 const bool unserialized = _unserialized;
524 _unserialized = false;
525 return unserialized;
526 }
527};
528
535TEST_F(SerializableFixture, SectionSerializationSimple)
536{
537 SerializableType serializable;
538
539 // Serialization
540 {
541 serializable.serializeSection(*cpt_out, "Section1");
542 ASSERT_EQ(getContents(*cpt_out, getCptPath()),
543 "\n[Section1]\n");
544 ASSERT_TRUE(serializable.checkAndResetSerialized());
545 ASSERT_FALSE(serializable.checkAndResetUnserialized());
546
547 serializable.serializeSection(*cpt_out, "Section2");
548 ASSERT_EQ(getContents(*cpt_out, getCptPath()),
549 "\n[Section1]\n\n[Section2]\n");
550 ASSERT_TRUE(serializable.checkAndResetSerialized());
551 ASSERT_FALSE(serializable.checkAndResetUnserialized());
552
553 serializable.serializeSection(*cpt_out, "Section3");
554 ASSERT_EQ(getContents(*cpt_out, getCptPath()),
555 "\n[Section1]\n\n[Section2]\n\n[Section3]\n");
556 ASSERT_TRUE(serializable.checkAndResetSerialized());
557 ASSERT_FALSE(serializable.checkAndResetUnserialized());
558 }
559
560 // Unserialization. Since the object has no serializable contents,
561 // just make sure it does not throw for existent and non-existent
562 // sections
563 {
564 ASSERT_NO_THROW(serializable.unserializeSection(*cpt_in, "Section1"));
565 ASSERT_FALSE(serializable.checkAndResetSerialized());
566 ASSERT_TRUE(serializable.checkAndResetUnserialized());
567
568 ASSERT_NO_THROW(serializable.unserializeSection(*cpt_in, "Section2"));
569 ASSERT_FALSE(serializable.checkAndResetSerialized());
570 ASSERT_TRUE(serializable.checkAndResetUnserialized());
571
572 ASSERT_NO_THROW(serializable.unserializeSection(*cpt_in, "Section3"));
573 ASSERT_FALSE(serializable.checkAndResetSerialized());
574 ASSERT_TRUE(serializable.checkAndResetUnserialized());
575
576 ASSERT_NO_THROW(serializable.unserializeSection(*cpt_in, "Section4"));
577 ASSERT_FALSE(serializable.checkAndResetSerialized());
578 ASSERT_TRUE(serializable.checkAndResetUnserialized());
579 }
580}
581
586{
587 int unserialized_integer;
588 Serializable::ScopedCheckpointSection scs(*cpt_in, "Section1");
589 ASSERT_ANY_THROW(paramIn(*cpt_in, "Param1", unserialized_integer));
590}
591
597{
598 const int integer = 5;
599 const double real = 3.7;
600 const bool boolean = true;
601 const std::string str = "string test";
602 const char character = 'c';
603
604 // Serialization
605 {
606 Serializable::ScopedCheckpointSection scs(*cpt_out, "Section1");
607 std::string expected = "\n[Section1]\n";
608
609 paramOut(*cpt_out, "Param1", integer);
610 expected += "Param1=5\n";
611 ASSERT_EQ(getContents(*cpt_out, getCptPath()), expected);
612
613 paramOut(*cpt_out, "Param2", real);
614 expected += "Param2=3.7\n";
615 ASSERT_EQ(getContents(*cpt_out, getCptPath()), expected);
616
617 paramOut(*cpt_out, "Param3", boolean);
618 expected += "Param3=true\n";
619 ASSERT_EQ(getContents(*cpt_out, getCptPath()), expected);
620
621 paramOut(*cpt_out, "Param4", str);
622 expected += "Param4=string test\n";
623 ASSERT_EQ(getContents(*cpt_out, getCptPath()), expected);
624
625 paramOut(*cpt_out, "Param5", character);
626 expected += "Param5=99\n";
627 ASSERT_EQ(getContents(*cpt_out, getCptPath()), expected);
628 }
629
630 // Unserialization
631 {
632 CheckpointIn cpt(getDirName());
633
634 int unserialized_integer;
635 double unserialized_real;
636 bool unserialized_boolean;
637 std::string unserialized_str;
638 char unserialized_character;
639
641
642 paramIn(cpt, "Param1", unserialized_integer);
643 ASSERT_EQ(integer, unserialized_integer);
644
645 paramIn(cpt, "Param2", unserialized_real);
646 ASSERT_EQ(real, unserialized_real);
647
648 paramIn(cpt, "Param3", unserialized_boolean);
649 ASSERT_EQ(boolean, unserialized_boolean);
650
651 paramIn(cpt, "Param4", unserialized_str);
652 ASSERT_EQ(str, unserialized_str);
653
654 paramIn(cpt, "Param5", unserialized_character);
655 ASSERT_EQ(character, unserialized_character);
656 }
657}
658
663TEST_F(SerializableFixture, ParamOutInMultipleSections)
664{
665 const int integer = 5;
666 const double real = 3.7;
667 const bool boolean = true;
668 const std::string str = "string test";
669 const char character = 'c';
670
671 // Serialization
672 {
673 Serializable::ScopedCheckpointSection scs(*cpt_out, "Section1");
674 std::string expected = "\n[Section1]\n";
675
676 paramOut(*cpt_out, "Param1", integer);
677 expected += "Param1=5\n";
678 ASSERT_EQ(getContents(*cpt_out, getCptPath()), expected);
679
680 paramOut(*cpt_out, "Param2", real);
681 expected += "Param2=3.7\n";
682 ASSERT_EQ(getContents(*cpt_out, getCptPath()), expected);
683
684 {
685 Serializable::ScopedCheckpointSection scs_2(*cpt_out, "Section2");
686 expected += "\n[Section1.Section2]\n";
687
688 paramOut(*cpt_out, "Param3", boolean);
689 expected += "Param3=true\n";
690 ASSERT_EQ(getContents(*cpt_out, getCptPath()),
691 expected);
692 }
693
694 // Possibly unexpected behavior: Since scs_2 has gone out of scope
695 // the user may expect that we'd go back to Section1; however, this
696 // is not the case, and Param4 is added to Section1.Section2
697 paramOut(*cpt_out, "Param4", str);
698 expected += "Param4=string test\n";
699 ASSERT_EQ(getContents(*cpt_out, getCptPath()), expected);
700
701 {
702 Serializable::ScopedCheckpointSection scs_3(*cpt_out, "Section3");
703 expected += "\n[Section1.Section3]\n";
704
705 Serializable::ScopedCheckpointSection scs_4(*cpt_out, "Section4");
706 expected += "\n[Section1.Section3.Section4]\n";
707
708 paramOut(*cpt_out, "Param5", character);
709 expected += "Param5=99\n";
710 ASSERT_EQ(getContents(*cpt_out, getCptPath()),
711 expected);
712 }
713 }
714
715 // Unserialization
716 {
717 CheckpointIn cpt(getDirName());
718
719 int unserialized_integer;
720 double unserialized_real;
721 bool unserialized_boolean;
722 std::string unserialized_str;
723 char unserialized_character;
724
726
727 paramIn(cpt, "Param1", unserialized_integer);
728 ASSERT_EQ(integer, unserialized_integer);
729
730 paramIn(cpt, "Param2", unserialized_real);
731 ASSERT_EQ(real, unserialized_real);
732
733 {
734 Serializable::ScopedCheckpointSection scs_2(cpt, "Section2");
735
736 paramIn(cpt, "Param3", unserialized_boolean);
737 ASSERT_EQ(boolean, unserialized_boolean);
738
739 // Due to the reason mentioned above on serialization, this param
740 // must be extracted within the scope of Section 2
741 paramIn(cpt, "Param4", unserialized_str);
742 ASSERT_EQ(str, unserialized_str);
743 }
744
745 {
746 Serializable::ScopedCheckpointSection scs_3(cpt, "Section3");
747 Serializable::ScopedCheckpointSection scs_4(cpt, "Section4");
748
749 paramIn(cpt, "Param5", unserialized_character);
750 ASSERT_EQ(character, unserialized_character);
751 }
752 }
753}
754
757{
758 const double real = 3.7;
759 const std::string str = "string test";
760
761 // Serialization
762 {
763 std::ofstream cpt(getCptPath());
765 paramOut(cpt, "Param2", real);
766 paramOut(cpt, "Param4", str);
767 }
768
769 // Unserialization
770 {
771 CheckpointIn cpt(getDirName());
772
773 int unserialized_integer;
774 double unserialized_real;
775 bool unserialized_boolean;
776 std::string unserialized_str;
777
779
780 // Optional without warning
781 gtestLogOutput.str("");
782 ASSERT_FALSE(optParamIn(cpt, "Param1", unserialized_integer, false));
783 ASSERT_EQ(gtestLogOutput.str(), "");
784
785 gtestLogOutput.str("");
786 ASSERT_TRUE(optParamIn(cpt, "Param2", unserialized_real, false));
787 ASSERT_EQ(real, unserialized_real);
788 ASSERT_EQ(gtestLogOutput.str(), "");
789
790 // Optional with default request for warning
791 gtestLogOutput.str("");
792 ASSERT_FALSE(optParamIn(cpt, "Param3", unserialized_boolean));
793 ASSERT_THAT(gtestLogOutput.str(),
794 ::testing::HasSubstr("warn: optional parameter Section1:Param3 "
795 "not present\n"));
796
797 gtestLogOutput.str("");
798 ASSERT_TRUE(optParamIn(cpt, "Param4", unserialized_str));
799 ASSERT_EQ(str, unserialized_str);
800 ASSERT_EQ(gtestLogOutput.str(), "");
801
802 // Explicit request for warning
803 gtestLogOutput.str("");
804 ASSERT_FALSE(optParamIn(cpt, "Param5", unserialized_boolean, true));
805 ASSERT_THAT(gtestLogOutput.str(),
806 ::testing::HasSubstr("warn: optional parameter Section1:Param5 "
807 "not present\n"));
808 }
809}
810
813{
814#ifndef NDEBUG
815 GTEST_SKIP() << "Skipping as assertions are "
816 "stripped out of fast builds";
817#endif
818
819 std::ofstream of(getCptPath());
820 CheckpointIn cpt(getDirName());
821 int unserialized_integer;
822 ASSERT_DEATH(paramIn(cpt, "Param1", unserialized_integer), "");
823}
824
826TEST_F(SerializeFixture, ArrayParamOutIn)
827{
828 const int integer[] = {5, 10, 15};
829 std::array<double, 4> real = {0.1, 1.345, 892.72, 1e+10};
830 std::list<bool> boolean = {true, false};
831 std::vector<std::string> str = {"a", "string", "test"};
832 std::set<uint64_t> uint64 = {12751928501, 13, 111111};
833 std::deque<uint8_t> uint8 = {17, 42, 255};
834
835 // Serialization
836 {
837 std::ofstream cpt(getCptPath());
839 std::string expected = "\n[Section1]\n";
840
841 arrayParamOut(cpt, "Param1", integer);
842 expected += "Param1=5 10 15\n";
843 ASSERT_EQ(getContents(cpt, getCptPath()), expected);
844
845 arrayParamOut(cpt, "Param2", real);
846 expected += "Param2=0.1 1.345 892.72 1e+10\n";
847 ASSERT_EQ(getContents(cpt, getCptPath()), expected);
848
849 arrayParamOut(cpt, "Param3", boolean);
850 expected += "Param3=true false\n";
851 ASSERT_EQ(getContents(cpt, getCptPath()), expected);
852
853 arrayParamOut(cpt, "Param4", str);
854 expected += "Param4=a string test\n";
855 ASSERT_EQ(getContents(cpt, getCptPath()), expected);
856
857 arrayParamOut(cpt, "Param5", uint64);
858 expected += "Param5=13 111111 12751928501\n";
859 ASSERT_EQ(getContents(cpt, getCptPath()), expected);
860
861 arrayParamOut(cpt, "Param6", uint8);
862 expected += "Param6=17 42 255\n";
863 ASSERT_EQ(getContents(cpt, getCptPath()), expected);
864 }
865
866 // Unserialization
867 {
868 CheckpointIn cpt(getDirName());
869
870 int unserialized_integer[3];
871 std::array<double, 4> unserialized_real;
872 std::list<bool> unserialized_boolean;
873 std::vector<std::string> unserialized_str;
874 std::set<uint64_t> unserialized_uint64;
875 std::deque<uint8_t> unserialized_uint8;
876
878
879 arrayParamIn(cpt, "Param1", unserialized_integer, 3);
880 ASSERT_THAT(unserialized_integer, testing::ElementsAre(5, 10, 15));
881
882 arrayParamIn(cpt, "Param2", unserialized_real.data(),
883 unserialized_real.size());
884 ASSERT_EQ(real, unserialized_real);
885
886 arrayParamIn(cpt, "Param3", unserialized_boolean);
887 ASSERT_EQ(boolean, unserialized_boolean);
888
889 arrayParamIn(cpt, "Param4", unserialized_str);
890 ASSERT_EQ(str, unserialized_str);
891
892 arrayParamIn(cpt, "Param5", unserialized_uint64);
893 ASSERT_EQ(uint64, unserialized_uint64);
894
895 arrayParamIn(cpt, "Param6", unserialized_uint8);
896 ASSERT_EQ(uint8, unserialized_uint8);
897 }
898}
899
905TEST_F(SerializeFixture, DISABLED_ArrayParamOutInSpacedStrings)
906{
907 std::vector<std::string> str = {"a string test", "for", "array param out"};
908
909 // Serialization
910 {
911 std::ofstream cpt(getCptPath());
913 std::string expected = "\n[Section1]\n";
914
915 arrayParamOut(cpt, "Param1", str);
916 expected += "Param1=string test for array param out\n";
917 ASSERT_EQ(getContents(cpt, getCptPath()), expected);
918 }
919
920 // Unserialization
921 {
922 CheckpointIn cpt(getDirName());
923
924 std::vector<std::string> unserialized_str;
925
927
928 arrayParamIn(cpt, "Param1", unserialized_str);
929 ASSERT_EQ(str, unserialized_str);
930 }
931}
932
937TEST_F(SerializeFixtureDeathTest, ArrayParamOutInSmaller)
938{
939 // Serialization
940 {
941 const int integer[] = {5, 10, 15};
942
943 std::ofstream cpt(getCptPath());
945 std::string expected = "\n[Section1]\n";
946
947 arrayParamOut(cpt, "Param1", integer);
948 expected += "Param1=5 10 15\n";
949 ASSERT_EQ(getContents(cpt, getCptPath()), expected);
950 }
951
952 // Unserialization
953 {
954 CheckpointIn cpt(getDirName());
955
956 int unserialized_integer[1];
957
959
960 ASSERT_ANY_THROW(arrayParamIn(cpt, "Param1", unserialized_integer, 2));
961 }
962}
963
965TEST_F(SerializeFixture, MappingParamOutIn)
966{
967 const int integers[] = {10, 32, 100};
968 std::array<double, 4> reals = {0.1, 1.345, 892.72, 1e+10};
969 const char* const names_ints[] = {"ten", "thirty-two", "one hundred"};
970 const char* const names_reals[] = {"first", "second", "third", "fourth"};
971
972 // Serialization
973 {
974 std::ofstream cpt(getCptPath());
976 std::string expected = "\n[Section1]\n";
977
978 mappingParamOut(cpt, "Integers", names_ints, integers, 3);
979 expected += "\n[Section1.Integers]\nten=10\nthirty-two=32\n"
980 "one hundred=100\n";
981 ASSERT_EQ(getContents(cpt, getCptPath()), expected);
982
983 mappingParamOut(cpt, "Reals", names_reals, reals.data(), reals.size());
984 expected += "\n[Section1.Reals]\nfirst=0.1\nsecond=1.345\n"
985 "third=892.72\nfourth=1e+10\n";
986 ASSERT_EQ(getContents(cpt, getCptPath()), expected);
987 }
988
989 // Unserialization
990 {
991 CheckpointIn cpt(getDirName());
992
993 int unserialized_integers[3];
994 std::array<double, 4> unserialized_reals;
995
996 mappingParamIn(cpt, "Section1.Integers", names_ints,
997 unserialized_integers, 3);
998 ASSERT_THAT(unserialized_integers, testing::ElementsAre(10, 32, 100));
999
1000 mappingParamIn(cpt, "Section1.Reals", names_reals,
1001 unserialized_reals.data(), unserialized_reals.size());
1002 ASSERT_EQ(unserialized_reals, reals);
1003 }
1004}
1005
1007TEST_F(SerializeFixture, MappingParamOutInMissing)
1008{
1009 const int integers[] = {10, 32, 100};
1010 std::array<double, 4> reals = {0.1, 1.345, 892.72, 1e+10};
1011
1012 // Serialization
1013 {
1014 const char* const names_ints[] = {"ten", "thirty-two", "one hundred"};
1015 const char* const names_reals[] =
1016 {"first", "second", "third", "fourth"};
1017
1018 std::ofstream cpt(getCptPath());
1020 std::string expected = "\n[Section1]\n";
1021
1022 mappingParamOut(cpt, "Integers", names_ints, integers, 3);
1023 expected += "\n[Section1.Integers]\nten=10\nthirty-two=32\n"
1024 "one hundred=100\n";
1025 ASSERT_EQ(getContents(cpt, getCptPath()), expected);
1026
1027 mappingParamOut(cpt, "Reals", names_reals, reals.data(), reals.size());
1028 expected += "\n[Section1.Reals]\nfirst=0.1\nsecond=1.345\n"
1029 "third=892.72\nfourth=1e+10\n";
1030 ASSERT_EQ(getContents(cpt, getCptPath()), expected);
1031 }
1032
1033 // Unserialization
1034 {
1035 const char* const names_ints[] = {"one hundred"};
1036 const char* const names_reals[] = {"first", "third"};
1037 std::array<double, 2> expected_reals = {0.1, 892.72};
1038
1039 CheckpointIn cpt(getDirName());
1040
1041 std::string err;
1042 int unserialized_integers[1];
1043 std::array<double, 2> unserialized_reals;
1044
1045 gtestLogOutput.str("");
1046 mappingParamIn(cpt, "Section1.Integers", names_ints,
1047 unserialized_integers, 1);
1048 ASSERT_THAT(unserialized_integers, testing::ElementsAre(100));
1049 err = gtestLogOutput.str();
1050 ASSERT_THAT(err, ::testing::HasSubstr("warn: unknown entry found in "
1051 "checkpoint: Section1.Integers thirty-two 32\n"));
1052 ASSERT_THAT(err, ::testing::HasSubstr("warn: unknown entry found in "
1053 "checkpoint: Section1.Integers ten 10\n"));
1054
1055 gtestLogOutput.str("");
1056 mappingParamIn(cpt, "Section1.Reals", names_reals,
1057 unserialized_reals.data(), unserialized_reals.size());
1058 ASSERT_EQ(unserialized_reals, expected_reals);
1059 err = gtestLogOutput.str();
1060 ASSERT_THAT(err, ::testing::HasSubstr("warn: unknown entry found in "
1061 "checkpoint: Section1.Reals fourth 1e+10\n"));
1062 ASSERT_THAT(err, ::testing::HasSubstr("warn: unknown entry found in "
1063 "checkpoint: Section1.Reals second 1.345\n"));
1064 }
1065}
1066
1071TEST_F(SerializeFixture, SerializeScalar)
1072{
1073 const int expected_integer = 5;
1074 const double expected_real = 3.7;
1075 const bool expected_boolean = true;
1076 const std::string expected_str = "string test";
1077
1078 // Serialization
1079 {
1080 const int integer = expected_integer;
1081 const double real = expected_real;
1082 const bool boolean = expected_boolean;
1083 const std::string str = expected_str;
1084
1085 std::ofstream cp(getCptPath());
1087 std::string expected = "\n[Section1]\n";
1088
1089 SERIALIZE_SCALAR(integer);
1090 expected += "integer=5\n";
1091 ASSERT_EQ(getContents(cp, getCptPath()), expected);
1092
1093 SERIALIZE_SCALAR(real);
1094 expected += "real=3.7\n";
1095 ASSERT_EQ(getContents(cp, getCptPath()), expected);
1096
1097 SERIALIZE_SCALAR(boolean);
1098 expected += "boolean=true\n";
1099 ASSERT_EQ(getContents(cp, getCptPath()), expected);
1100
1101 SERIALIZE_SCALAR(str);
1102 expected += "str=string test\n";
1103 ASSERT_EQ(getContents(cp, getCptPath()), expected);
1104 }
1105
1106 // Unserialization
1107 {
1108 CheckpointIn cp(getDirName());
1109
1110 int integer;
1111 double real;
1112 bool boolean;
1113 std::string str;
1114
1116
1117 UNSERIALIZE_SCALAR(integer);
1118 ASSERT_EQ(integer, expected_integer);
1119
1120 UNSERIALIZE_SCALAR(real);
1121 ASSERT_EQ(real, expected_real);
1122
1123 UNSERIALIZE_SCALAR(boolean);
1124 ASSERT_EQ(boolean, expected_boolean);
1125
1126 UNSERIALIZE_SCALAR(str);
1127 ASSERT_EQ(str, expected_str);
1128 }
1129}
1130
1132TEST_F(SerializeFixture, UnserializeOptScalar)
1133{
1134 const double expected_real = 3.7;
1135 const std::string expected_str = "string test";
1136
1137 // Serialization
1138 {
1139 const double real = expected_real;
1140 const std::string str = expected_str;
1141
1142 std::ofstream cp(getCptPath());
1144 SERIALIZE_SCALAR(real);
1145 SERIALIZE_SCALAR(str);
1146 }
1147
1148 // Unserialization
1149 {
1150 CheckpointIn cp(getDirName());
1151
1152 int integer;
1153 double real;
1154 bool boolean;
1155 std::string str;
1156
1158
1159 // Optional without warning
1160 ASSERT_FALSE(UNSERIALIZE_OPT_SCALAR(integer));
1161
1162 ASSERT_TRUE(UNSERIALIZE_OPT_SCALAR(real));
1163 ASSERT_EQ(real, expected_real);
1164
1165 // Optional with default request for warning
1166 ASSERT_FALSE(UNSERIALIZE_OPT_SCALAR(boolean));
1167
1168 ASSERT_TRUE(UNSERIALIZE_OPT_SCALAR(str));
1169 ASSERT_EQ(str, expected_str);
1170 }
1171}
1172
1178{
1179 enum Number
1180 {
1181 ZERO,
1182 TEN=10,
1183 THIRTY_TWO=32
1184 };
1185 const Number expected_val = ZERO;
1186 const Number expected_val_2 = THIRTY_TWO;
1187
1188 // Serialization
1189 {
1190 const Number zero = expected_val;
1191 const Number thirty_two = expected_val_2;
1192
1193 std::ofstream cp(getCptPath());
1195 std::string expected = "\n[Section1]\n";
1196
1197 SERIALIZE_ENUM(zero);
1198 expected += "zero=0\n";
1199 ASSERT_EQ(getContents(cp, getCptPath()), expected);
1200
1201 SERIALIZE_ENUM(thirty_two);
1202 expected += "thirty_two=32\n";
1203 ASSERT_EQ(getContents(cp, getCptPath()), expected);
1204 }
1205
1206 // Unserialization
1207 {
1208 CheckpointIn cp(getDirName());
1209
1210 Number zero;
1211 Number thirty_two;
1212
1214
1215 UNSERIALIZE_ENUM(zero);
1216 ASSERT_EQ(zero, expected_val);
1217
1218 UNSERIALIZE_ENUM(thirty_two);
1219 ASSERT_EQ(thirty_two, expected_val_2);
1220 }
1221}
1222
1224TEST_F(SerializeFixture, SerializeArray)
1225{
1226 std::array<double, 4> expected_real = {0.1, 1.345, 892.72, 1e+10};
1227
1228 // Serialization
1229 {
1230 const int integer[] = {5, 10, 15};
1231 const double *real = expected_real.data();
1232
1233 std::ofstream cp(getCptPath());
1235 std::string expected = "\n[Section1]\n";
1236
1237 SERIALIZE_ARRAY(integer, 3);
1238 expected += "integer=5 10 15\n";
1239 ASSERT_EQ(getContents(cp, getCptPath()), expected);
1240
1241 SERIALIZE_ARRAY(real, expected_real.size());
1242 expected += "real=0.1 1.345 892.72 1e+10\n";
1243 ASSERT_EQ(getContents(cp, getCptPath()), expected);
1244 }
1245
1246 // Unserialization
1247 {
1248 CheckpointIn cp(getDirName());
1249
1250 int integer[3];
1251 std::array<double, 4> real_array;
1252 double *real = real_array.data();
1253
1255
1256 UNSERIALIZE_ARRAY(integer, 3);
1257 ASSERT_THAT(integer, testing::ElementsAre(5, 10, 15));
1258
1259 UNSERIALIZE_ARRAY(real, expected_real.size());
1260 ASSERT_EQ(real_array, expected_real);
1261 }
1262}
1263
1265TEST_F(SerializeFixture, SerializeContainer)
1266{
1267 std::list<bool> expected_boolean = {true, false};
1268 std::vector<std::string> expected_str = {"a", "string", "test"};
1269 std::set<uint64_t> expected_uint64 = {12751928501, 13, 111111};
1270 std::deque<uint8_t> expected_uint8 = {17, 42, 255};
1271
1272 // Serialization
1273 {
1274 const std::list<bool> boolean = expected_boolean;
1275 const std::vector<std::string> str = expected_str;
1276 const std::set<uint64_t> uint64 = expected_uint64;
1277 const std::deque<uint8_t> uint8 = expected_uint8;
1278
1279 std::ofstream cp(getCptPath());
1281 std::string expected = "\n[Section1]\n";
1282
1283 SERIALIZE_CONTAINER(boolean);
1284 expected += "boolean=true false\n";
1285 ASSERT_EQ(getContents(cp, getCptPath()), expected);
1286
1288 expected += "str=a string test\n";
1289 ASSERT_EQ(getContents(cp, getCptPath()), expected);
1290
1291 SERIALIZE_CONTAINER(uint64);
1292 expected += "uint64=13 111111 12751928501\n";
1293 ASSERT_EQ(getContents(cp, getCptPath()), expected);
1294
1295 SERIALIZE_CONTAINER(uint8);
1296 expected += "uint8=17 42 255\n";
1297 ASSERT_EQ(getContents(cp, getCptPath()), expected);
1298 }
1299
1300 // Unserialization
1301 {
1302 CheckpointIn cp(getDirName());
1303
1304 std::list<bool> boolean;
1306 std::set<uint64_t> uint64;
1307 std::deque<uint8_t> uint8;
1308
1310
1311 UNSERIALIZE_CONTAINER(boolean);
1312 ASSERT_EQ(boolean, expected_boolean);
1313
1315 ASSERT_EQ(str, expected_str);
1316
1317 UNSERIALIZE_CONTAINER(uint64);
1318 ASSERT_EQ(uint64, expected_uint64);
1319
1320 UNSERIALIZE_CONTAINER(uint8);
1321 ASSERT_EQ(uint8, expected_uint8);
1322 }
1323}
1324
1326TEST_F(SerializeFixture, SerializeMapping)
1327{
1328 const int expected_integers[] = {10, 32, 100};
1329 std::array<double, 4> expected_reals = {0.1, 1.345, 892.72, 1e+10};
1330 const char* const names_ints[] = {"ten", "thirty-two", "one hundred"};
1331 const char* const names_reals[] = {"first", "second", "third", "fourth"};
1332
1333 // Serialization
1334 {
1335 const int *integers = expected_integers;
1336 const double *reals = expected_reals.data();
1337
1338 std::ofstream cp(getCptPath());
1340 std::string expected = "\n[Section1]\n";
1341
1342 SERIALIZE_MAPPING(integers, names_ints, 3);
1343 expected += "\n[Section1.integers]\nten=10\nthirty-two=32\n"
1344 "one hundred=100\n";
1345 ASSERT_EQ(getContents(cp, getCptPath()), expected);
1346
1347 SERIALIZE_MAPPING(reals, names_reals, expected_reals.size());
1348 expected += "\n[Section1.reals]\nfirst=0.1\nsecond=1.345\n"
1349 "third=892.72\nfourth=1e+10\n";
1350 ASSERT_EQ(getContents(cp, getCptPath()), expected);
1351 }
1352
1353 // Unserialization
1354 {
1355 CheckpointIn cp(getDirName());
1356
1357 int integers[3];
1358 double reals[4];
1359
1361
1362 UNSERIALIZE_MAPPING(integers, names_ints, 3);
1363 ASSERT_THAT(integers, testing::ElementsAre(10, 32, 100));
1364
1365 UNSERIALIZE_MAPPING(reals, names_reals, expected_reals.size());
1366 ASSERT_THAT(reals, testing::ElementsAre(0.1, 1.345, 892.72, 1e+10));
1367 }
1368}
void TearDown() override
std::unique_ptr< CheckpointIn > cpt
void SetUp() override
A fixture to handle checkpoint in and out variables, as well as the testing of the temporary director...
std::unique_ptr< CheckpointIn > cpt_in
void SetUp() override
std::unique_ptr< std::ofstream > cpt_out
void TearDown() override
bool checkAndResetUnserialized()
Checks if unserialize() has been called and then marks it as not called.
void unserialize(CheckpointIn &cp) override
Unserialize an object.
bool checkAndResetSerialized()
Checks if serialize() has been called and then marks it as not called.
void serialize(CheckpointOut &cp) const override
Serialize an object.
Basic support for object serialization.
Definition serialize.hh:170
Fixture class that handles temporary directory creation.
std::string getDirName() const
Get the name of the directory we have created on SetUp.
std::string getCptPath() const
Get the path to the checkpoint file.
static std::string generateTempDirName()
Generate a temporary directory name.
STL deque class.
Definition stl.hh:44
STL list class.
Definition stl.hh:51
STL vector class.
Definition stl.hh:37
std::vector< SwitchingFiber * > expected({ &a, &b, &a, &a, &a, &b, &c, &a, &c, &c, &c })
bool optParamIn(CheckpointIn &cp, const std::string &name, T &param, bool do_warn=true)
This function is used for restoring optional parameters from the checkpoint.
Definition serialize.hh:357
#define UNSERIALIZE_CONTAINER(member)
Definition serialize.hh:634
#define SERIALIZE_ENUM(scalar)
Definition serialize.hh:591
#define UNSERIALIZE_OPT_SCALAR(scalar)
Definition serialize.hh:582
static std::string setDir(const std::string &base_name)
Set the current directory.
Definition serialize.cc:142
void serializeSection(CheckpointOut &cp, const char *name) const
Serialize an object into a new section.
Definition serialize.cc:74
static const std::string & currentSection()
Gets the fully-qualified name of the active section.
Definition serialize.cc:130
#define UNSERIALIZE_ARRAY(member, size)
Definition serialize.hh:618
#define SERIALIZE_ARRAY(member, size)
Definition serialize.hh:610
#define SERIALIZE_CONTAINER(member)
Definition serialize.hh:626
static std::string dir()
Get the current checkout directory name.
Definition serialize.cc:157
#define UNSERIALIZE_ENUM(scalar)
Definition serialize.hh:598
static void generateCheckpointOut(const std::string &cpt_dir, std::ofstream &outstream)
Generate a checkpoint file so that the serialization can be routed to it.
Definition serialize.cc:88
void unserializeSection(CheckpointIn &cp, const char *name)
Unserialize an a child object.
Definition serialize.cc:81
Bitfield< 6 > err
Bitfield< 9 > e
Definition misc_types.hh:65
Bitfield< 24, 22 > is
Bitfield< 18 > scs
Bitfield< 11 > of
Definition misc.hh:581
Bitfield< 17 > os
Definition misc.hh:838
Copyright (c) 2024 - Pranith Kumar Copyright (c) 2020 Inria All rights reserved.
Definition binary32.hh:36
void mappingParamOut(CheckpointOut &os, const char *sectionName, const char *const names[], const T *param, unsigned size)
Serialize a mapping represented as two arrays: one containing names and the other containing values.
Definition serialize.hh:516
std::ostream CheckpointOut
Definition serialize.hh:66
void paramOut(CheckpointOut &cp, const std::string &name, ExtMachInst const &machInst)
Definition types.cc:40
void paramIn(CheckpointIn &cp, const std::string &name, ExtMachInst &machInst)
Definition types.cc:72
void arrayParamOut(CheckpointOut &cp, const std::string &name, const CircleBuf< T > &param)
Definition circlebuf.hh:247
thread_local GTestLogOutput gtestLogOutput
Definition logging.cc:33
void mappingParamIn(CheckpointIn &cp, const char *sectionName, const char *const names[], T *param, unsigned size)
Restore mappingParamOut.
Definition serialize.hh:530
void arrayParamIn(CheckpointIn &cp, const std::string &name, CircleBuf< T > &param)
Definition circlebuf.hh:257
#define UNSERIALIZE_MAPPING(member, names, size)
Definition serialize.hh:666
#define UNSERIALIZE_SCALAR(scalar)
Definition serialize.hh:575
#define SERIALIZE_SCALAR(scalar)
Definition serialize.hh:568
#define SERIALIZE_MAPPING(member, names, size)
Definition serialize.hh:660
std::string getString(std::istream &is)
SerializationFixture SerializeFixture
GTestTickHandler tickHandler
bool dirExists(std::string dir)
std::string getContents(std::ofstream &cpt, std::string filename)
Flushes the checkpoint and reads its contents.
TEST_F(SerializeFixtureDeathTest, ConstructorFailure)
Test constructor failure by requesting the creation of a checkpoint in a non-existent dir.
TEST(CheckpointInTest, SetGetDirSlash)
Tests that when setting a checkpoint dir it always ends with a slash.

Generated on Tue Jun 18 2024 16:24:06 for gem5 by doxygen 1.11.0