1aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo//
2aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// Copyright (C) 2012 The Android Open Source Project
3aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo//
4aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// Licensed under the Apache License, Version 2.0 (the "License");
5aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// you may not use this file except in compliance with the License.
6aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// You may obtain a copy of the License at
7aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo//
8aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo//      http://www.apache.org/licenses/LICENSE-2.0
9aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo//
10aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// Unless required by applicable law or agreed to in writing, software
11aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// distributed under the License is distributed on an "AS IS" BASIS,
12aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// See the License for the specific language governing permissions and
14aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// limitations under the License.
15aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo//
1649fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
1739910dcd1d68987ccee7c3031dc269233a8490bbAlex Deymo#ifndef UPDATE_ENGINE_COMMON_TEST_UTILS_H_
1839910dcd1d68987ccee7c3031dc269233a8490bbAlex Deymo#define UPDATE_ENGINE_COMMON_TEST_UTILS_H_
1949fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
202c2b884a4547407759e50681bb7bc49e3589d4feGilad Arnold#include <sys/stat.h>
212c2b884a4547407759e50681bb7bc49e3589d4feGilad Arnold#include <sys/types.h>
222c2b884a4547407759e50681bb7bc49e3589d4feGilad Arnold#include <unistd.h>
232c2b884a4547407759e50681bb7bc49e3589d4feGilad Arnold
2452490e776a9d34a94fb18ab1fe7d416425e94ddaAlex Deymo// Streams used for gtest's PrintTo() functions.
2552490e776a9d34a94fb18ab1fe7d416425e94ddaAlex Deymo#include <iostream>  // NOLINT(readability/streams)
2602f7c1dee242f490143791dbb73fa23fa3007cfaBen Chan#include <memory>
27c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com#include <set>
2849fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com#include <string>
29c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com#include <vector>
305c7d97590b51ae9e85dde1e37a3fd91d06f7991dThieu Le
3153556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo#include <base/callback.h>
322b19cfbcdb1aa8c5d1f338d19312fe14b6734bd5Alex Deymo#include <base/files/file_path.h>
33371615b025bdd8106faf65c1ba7439a1236f21bcSen Jiang#include <base/files/scoped_temp_dir.h>
34c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com#include <gtest/gtest.h>
355c7d97590b51ae9e85dde1e37a3fd91d06f7991dThieu Le
3639910dcd1d68987ccee7c3031dc269233a8490bbAlex Deymo#include "update_engine/common/action.h"
3739910dcd1d68987ccee7c3031dc269233a8490bbAlex Deymo#include "update_engine/common/subprocess.h"
3839910dcd1d68987ccee7c3031dc269233a8490bbAlex Deymo#include "update_engine/common/utils.h"
3952490e776a9d34a94fb18ab1fe7d416425e94ddaAlex Deymo#include "update_engine/update_metadata.pb.h"
4049fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
4149fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com// These are some handy functions for unittests.
4249fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
4349fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.comnamespace chromeos_update_engine {
4452490e776a9d34a94fb18ab1fe7d416425e94ddaAlex Deymo
4552490e776a9d34a94fb18ab1fe7d416425e94ddaAlex Deymo// PrintTo() functions are used by gtest to log these objects. These PrintTo()
4652490e776a9d34a94fb18ab1fe7d416425e94ddaAlex Deymo// functions must be defined in the same namespace as the first argument.
4752490e776a9d34a94fb18ab1fe7d416425e94ddaAlex Deymovoid PrintTo(const Extent& extent, ::std::ostream* os);
4864d9878470aa7b388e971862181daf6260851602Alex Deymovoid PrintTo(const ErrorCode& error_code, ::std::ostream* os);
4952490e776a9d34a94fb18ab1fe7d416425e94ddaAlex Deymo
5010875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymonamespace test_utils {
5110875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo
5210875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo// 300 byte pseudo-random string. Not null terminated.
5310875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo// This does not gzip compress well.
54f68bbbc952aa9a71898e4939b5f36187fa564a50Alex Vakulenkoextern const uint8_t kRandomString[300];
5549fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
5649fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com// Writes the data passed to path. The file at path will be overwritten if it
5749fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com// exists. Returns true on success, false otherwise.
583f39d5cc753905874d8d93bef94f857b8808f19eAlex Vakulenkobool WriteFileVector(const std::string& path, const brillo::Blob& data);
59c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.combool WriteFileString(const std::string& path, const std::string& data);
6049fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
61cbc2274c4160805bf726df872390112654816ca7Alex Deymo// Binds provided |filename| to an unused loopback device, whose name is written
62cbc2274c4160805bf726df872390112654816ca7Alex Deymo// to the string pointed to by |out_lo_dev_name|. The new loop device will be
63cbc2274c4160805bf726df872390112654816ca7Alex Deymo// read-only unless |writable| is set to true. Returns true on success, false
64cbc2274c4160805bf726df872390112654816ca7Alex Deymo// otherwise (along with corresponding test failures), in which case the content
65cbc2274c4160805bf726df872390112654816ca7Alex Deymo// of |out_lo_dev_name| is unknown.
66cbc2274c4160805bf726df872390112654816ca7Alex Deymobool BindToUnusedLoopDevice(const std::string& filename,
67cbc2274c4160805bf726df872390112654816ca7Alex Deymo                            bool writable,
68cbc2274c4160805bf726df872390112654816ca7Alex Deymo                            std::string* out_lo_dev_name);
69cbc2274c4160805bf726df872390112654816ca7Alex Deymobool UnbindLoopDevice(const std::string& lo_dev_name);
70c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com
71c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com// Returns true iff a == b
723f39d5cc753905874d8d93bef94f857b8808f19eAlex Vakulenkobool ExpectVectorsEq(const brillo::Blob& a, const brillo::Blob& b);
73c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com
74c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.cominline int System(const std::string& cmd) {
75c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com  return system(cmd.c_str());
76c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com}
77c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com
782c2b884a4547407759e50681bb7bc49e3589d4feGilad Arnoldinline int Symlink(const std::string& oldpath, const std::string& newpath) {
792c2b884a4547407759e50681bb7bc49e3589d4feGilad Arnold  return symlink(oldpath.c_str(), newpath.c_str());
802c2b884a4547407759e50681bb7bc49e3589d4feGilad Arnold}
812c2b884a4547407759e50681bb7bc49e3589d4feGilad Arnold
822c2b884a4547407759e50681bb7bc49e3589d4feGilad Arnoldinline int Chmod(const std::string& path, mode_t mode) {
832c2b884a4547407759e50681bb7bc49e3589d4feGilad Arnold  return chmod(path.c_str(), mode);
842c2b884a4547407759e50681bb7bc49e3589d4feGilad Arnold}
852c2b884a4547407759e50681bb7bc49e3589d4feGilad Arnold
862c2b884a4547407759e50681bb7bc49e3589d4feGilad Arnoldinline int Mkdir(const std::string& path, mode_t mode) {
872c2b884a4547407759e50681bb7bc49e3589d4feGilad Arnold  return mkdir(path.c_str(), mode);
882c2b884a4547407759e50681bb7bc49e3589d4feGilad Arnold}
892c2b884a4547407759e50681bb7bc49e3589d4feGilad Arnold
9030dedd82be72ffa9bbe570e9c95166ec6bcc7792Gilad Arnoldinline int Chdir(const std::string& path) {
9130dedd82be72ffa9bbe570e9c95166ec6bcc7792Gilad Arnold  return chdir(path.c_str());
9230dedd82be72ffa9bbe570e9c95166ec6bcc7792Gilad Arnold}
9330dedd82be72ffa9bbe570e9c95166ec6bcc7792Gilad Arnold
94d15c546ed794293d0a63770467a0f3c4c84c6214Alex Deymo// Reads a symlink from disk. Returns empty string on failure.
95d15c546ed794293d0a63770467a0f3c4c84c6214Alex Deymostd::string Readlink(const std::string& path);
96d15c546ed794293d0a63770467a0f3c4c84c6214Alex Deymo
9710875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo// Checks if xattr is supported in the directory specified by
9810875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo// |dir_path| which must be writable. Returns true if the feature is
99f68bbbc952aa9a71898e4939b5f36187fa564a50Alex Vakulenko// supported, false if not or if an error occurred.
10010875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymobool IsXAttrSupported(const base::FilePath& dir_path);
101c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com
1023f39d5cc753905874d8d93bef94f857b8808f19eAlex Vakulenkovoid FillWithData(brillo::Blob* buffer);
103c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com
10410875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo// Class to unmount FS when object goes out of scope
10510875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymoclass ScopedFilesystemUnmounter {
10610875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo public:
10710875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo  explicit ScopedFilesystemUnmounter(const std::string& mountpoint)
10810875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo      : mountpoint_(mountpoint),
10910875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo        should_unmount_(true) {}
11010875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo  ~ScopedFilesystemUnmounter() {
11110875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo    if (should_unmount_) {
11210875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo      utils::UnmountFilesystem(mountpoint_);
11310875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo    }
11410875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo  }
11510875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo  void set_should_unmount(bool unmount) { should_unmount_ = unmount; }
11610875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo private:
11710875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo  const std::string mountpoint_;
11810875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo  bool should_unmount_;
11910875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo  DISALLOW_COPY_AND_ASSIGN(ScopedFilesystemUnmounter);
12010875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo};
12110875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo
12258e8b1f8b32b355d879008572648fd621873711dDon Garrettclass ScopedLoopbackDeviceBinder {
12309e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes public:
124cbc2274c4160805bf726df872390112654816ca7Alex Deymo  ScopedLoopbackDeviceBinder(const std::string& file,
125cbc2274c4160805bf726df872390112654816ca7Alex Deymo                             bool writable,
126cbc2274c4160805bf726df872390112654816ca7Alex Deymo                             std::string* dev) {
127cbc2274c4160805bf726df872390112654816ca7Alex Deymo    is_bound_ = BindToUnusedLoopDevice(file, writable, &dev_);
12819a45f0eda0917b7788b925b501e774208474fdeGilad Arnold    EXPECT_TRUE(is_bound_);
12958e8b1f8b32b355d879008572648fd621873711dDon Garrett
13019a45f0eda0917b7788b925b501e774208474fdeGilad Arnold    if (is_bound_ && dev)
13158e8b1f8b32b355d879008572648fd621873711dDon Garrett      *dev = dev_;
13258e8b1f8b32b355d879008572648fd621873711dDon Garrett  }
13358e8b1f8b32b355d879008572648fd621873711dDon Garrett
13458e8b1f8b32b355d879008572648fd621873711dDon Garrett  ~ScopedLoopbackDeviceBinder() {
13519a45f0eda0917b7788b925b501e774208474fdeGilad Arnold    if (!is_bound_)
13619a45f0eda0917b7788b925b501e774208474fdeGilad Arnold      return;
13719a45f0eda0917b7788b925b501e774208474fdeGilad Arnold
138cf56248d8b176c1ba024a7040067bdde18112beaDarin Petkov    for (int retry = 0; retry < 5; retry++) {
139cbc2274c4160805bf726df872390112654816ca7Alex Deymo      if (UnbindLoopDevice(dev_))
140cf56248d8b176c1ba024a7040067bdde18112beaDarin Petkov        return;
141cf56248d8b176c1ba024a7040067bdde18112beaDarin Petkov      sleep(1);
142cf56248d8b176c1ba024a7040067bdde18112beaDarin Petkov    }
143cf56248d8b176c1ba024a7040067bdde18112beaDarin Petkov    ADD_FAILURE();
14409e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes  }
14558e8b1f8b32b355d879008572648fd621873711dDon Garrett
14619a45f0eda0917b7788b925b501e774208474fdeGilad Arnold  const std::string &dev() {
14719a45f0eda0917b7788b925b501e774208474fdeGilad Arnold    EXPECT_TRUE(is_bound_);
14819a45f0eda0917b7788b925b501e774208474fdeGilad Arnold    return dev_;
14919a45f0eda0917b7788b925b501e774208474fdeGilad Arnold  }
15058e8b1f8b32b355d879008572648fd621873711dDon Garrett
151c33faebbd0b26cedb7ef51889c405cf85d79be0cGilad Arnold  bool is_bound() const { return is_bound_; }
152c33faebbd0b26cedb7ef51889c405cf85d79be0cGilad Arnold
15309e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes private:
15458e8b1f8b32b355d879008572648fd621873711dDon Garrett  std::string dev_;
15519a45f0eda0917b7788b925b501e774208474fdeGilad Arnold  bool is_bound_;
15658e8b1f8b32b355d879008572648fd621873711dDon Garrett  DISALLOW_COPY_AND_ASSIGN(ScopedLoopbackDeviceBinder);
15709e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes};
15809e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes
159f9185170a9763e493e77ffdc5b1f057c3bd3b11eAndrew de los Reyesclass ScopedTempFile {
160f9185170a9763e493e77ffdc5b1f057c3bd3b11eAndrew de los Reyes public:
161bffa06080ec8bd5d196cbfadf2023f78b6e89169Alex Deymo  ScopedTempFile() : ScopedTempFile("update_engine_test_temp_file.XXXXXX") {}
162bffa06080ec8bd5d196cbfadf2023f78b6e89169Alex Deymo
163bffa06080ec8bd5d196cbfadf2023f78b6e89169Alex Deymo  explicit ScopedTempFile(const std::string& pattern) {
164bffa06080ec8bd5d196cbfadf2023f78b6e89169Alex Deymo    EXPECT_TRUE(utils::MakeTempFile(pattern, &path_, nullptr));
165f9185170a9763e493e77ffdc5b1f057c3bd3b11eAndrew de los Reyes    unlinker_.reset(new ScopedPathUnlinker(path_));
166f9185170a9763e493e77ffdc5b1f057c3bd3b11eAndrew de los Reyes  }
167bffa06080ec8bd5d196cbfadf2023f78b6e89169Alex Deymo
1682c131bbf81d8c02ade163b939c96e44aa93765e9Alex Deymo  const std::string& path() const { return path_; }
169bffa06080ec8bd5d196cbfadf2023f78b6e89169Alex Deymo
170f9185170a9763e493e77ffdc5b1f057c3bd3b11eAndrew de los Reyes private:
171f9185170a9763e493e77ffdc5b1f057c3bd3b11eAndrew de los Reyes  std::string path_;
17202f7c1dee242f490143791dbb73fa23fa3007cfaBen Chan  std::unique_ptr<ScopedPathUnlinker> unlinker_;
173f9185170a9763e493e77ffdc5b1f057c3bd3b11eAndrew de los Reyes};
174f9185170a9763e493e77ffdc5b1f057c3bd3b11eAndrew de los Reyes
17510875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymoclass ScopedLoopMounter {
17610875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo public:
17710875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo  explicit ScopedLoopMounter(const std::string& file_path,
17810875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo                             std::string* mnt_path,
17910875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo                             unsigned long flags);  // NOLINT(runtime/int)
18010875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo
18110875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo private:
18210875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo  // These objects must be destructed in the following order:
18310875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo  //   ScopedFilesystemUnmounter (the file system must be unmounted first)
18410875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo  //   ScopedLoopbackDeviceBinder (then the loop device can be deleted)
18510875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo  //   ScopedDirRemover (then the mount point can be deleted)
186371615b025bdd8106faf65c1ba7439a1236f21bcSen Jiang  base::ScopedTempDir temp_dir_;
18710875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo  std::unique_ptr<ScopedLoopbackDeviceBinder> loop_binder_;
18810875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo  std::unique_ptr<ScopedFilesystemUnmounter> unmounter_;
18910875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo};
19010875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo
1912b19cfbcdb1aa8c5d1f338d19312fe14b6734bd5Alex Deymo// Returns the path where the build artifacts are stored. This is the directory
1922b19cfbcdb1aa8c5d1f338d19312fe14b6734bd5Alex Deymo// where the unittest executable is being run from.
1932b19cfbcdb1aa8c5d1f338d19312fe14b6734bd5Alex Deymobase::FilePath GetBuildArtifactsPath();
194260f03bc4d3a3de436e056c686c814444358823aSen Jiang// Returns the path of the build artifact specified in |relative_path|.
195260f03bc4d3a3de436e056c686c814444358823aSen Jiangstd::string GetBuildArtifactsPath(const std::string& relative_path);
19610875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo
1972b19cfbcdb1aa8c5d1f338d19312fe14b6734bd5Alex Deymo}  // namespace test_utils
19810875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo
19910875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo// Useful actions for test. These need to be defined in the
20010875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo// chromeos_update_engine namespace.
201c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com
202c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.comclass NoneType;
203c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com
204c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.comtemplate<typename T>
205c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.comclass ObjectFeederAction;
206c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com
207c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.comtemplate<typename T>
208f9cb98c0cacccca803db48502c7bd461d04cb6b0Ben Chanclass ActionTraits<ObjectFeederAction<T>> {
209c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com public:
210c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com  typedef T OutputObjectType;
211c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com  typedef NoneType InputObjectType;
212c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com};
213c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com
214c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com// This is a simple Action class for testing. It feeds an object into
215c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com// another action.
216c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.comtemplate<typename T>
217f9cb98c0cacccca803db48502c7bd461d04cb6b0Ben Chanclass ObjectFeederAction : public Action<ObjectFeederAction<T>> {
218c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com public:
219c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com  typedef NoneType InputObjectType;
220c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com  typedef T OutputObjectType;
221c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com  void PerformAction() {
222c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com    LOG(INFO) << "feeder running!";
223c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com    CHECK(this->processor_);
224c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com    if (this->HasOutputPipe()) {
225c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com      this->SetOutputObject(out_obj_);
226c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com    }
227d1c4d2dd3daed1d507038046c0355fbafb85260cGilad Arnold    this->processor_->ActionComplete(this, ErrorCode::kSuccess);
228c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com  }
229c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com  static std::string StaticType() { return "ObjectFeederAction"; }
230c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com  std::string Type() const { return StaticType(); }
231c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com  void set_obj(const T& out_obj) {
232c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com    out_obj_ = out_obj;
233c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com  }
234c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com private:
235c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com  T out_obj_;
236c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com};
237c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com
238c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.comtemplate<typename T>
239c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.comclass ObjectCollectorAction;
240c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com
241c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.comtemplate<typename T>
242f9cb98c0cacccca803db48502c7bd461d04cb6b0Ben Chanclass ActionTraits<ObjectCollectorAction<T>> {
243c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com public:
244c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com  typedef NoneType OutputObjectType;
245c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com  typedef T InputObjectType;
246c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com};
247c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com
248c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com// This is a simple Action class for testing. It receives an object from
249c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com// another action.
250c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.comtemplate<typename T>
251f9cb98c0cacccca803db48502c7bd461d04cb6b0Ben Chanclass ObjectCollectorAction : public Action<ObjectCollectorAction<T>> {
252c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com public:
253c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com  typedef T InputObjectType;
254c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com  typedef NoneType OutputObjectType;
255c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com  void PerformAction() {
256c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com    LOG(INFO) << "collector running!";
257c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com    ASSERT_TRUE(this->processor_);
258c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com    if (this->HasInputObject()) {
259c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com      object_ = this->GetInputObject();
260c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com    }
261d1c4d2dd3daed1d507038046c0355fbafb85260cGilad Arnold    this->processor_->ActionComplete(this, ErrorCode::kSuccess);
262c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com  }
263c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com  static std::string StaticType() { return "ObjectCollectorAction"; }
264c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com  std::string Type() const { return StaticType(); }
265c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com  const T& object() const { return object_; }
266c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com private:
267c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com  T object_;
268c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com};
269c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com
27049fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com}  // namespace chromeos_update_engine
27149fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
27239910dcd1d68987ccee7c3031dc269233a8490bbAlex Deymo#endif  // UPDATE_ENGINE_COMMON_TEST_UTILS_H_
273