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>
33c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com#include <gtest/gtest.h>
345c7d97590b51ae9e85dde1e37a3fd91d06f7991dThieu Le
3539910dcd1d68987ccee7c3031dc269233a8490bbAlex Deymo#include "update_engine/common/action.h"
3639910dcd1d68987ccee7c3031dc269233a8490bbAlex Deymo#include "update_engine/common/subprocess.h"
3739910dcd1d68987ccee7c3031dc269233a8490bbAlex Deymo#include "update_engine/common/utils.h"
3852490e776a9d34a94fb18ab1fe7d416425e94ddaAlex Deymo#include "update_engine/update_metadata.pb.h"
3949fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
4049fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com// These are some handy functions for unittests.
4149fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
4249fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.comnamespace chromeos_update_engine {
4352490e776a9d34a94fb18ab1fe7d416425e94ddaAlex Deymo
4452490e776a9d34a94fb18ab1fe7d416425e94ddaAlex Deymo// PrintTo() functions are used by gtest to log these objects. These PrintTo()
4552490e776a9d34a94fb18ab1fe7d416425e94ddaAlex Deymo// functions must be defined in the same namespace as the first argument.
4652490e776a9d34a94fb18ab1fe7d416425e94ddaAlex Deymovoid PrintTo(const Extent& extent, ::std::ostream* os);
4764d9878470aa7b388e971862181daf6260851602Alex Deymovoid PrintTo(const ErrorCode& error_code, ::std::ostream* os);
4852490e776a9d34a94fb18ab1fe7d416425e94ddaAlex Deymo
4910875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymonamespace test_utils {
5010875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo
5110875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo// 300 byte pseudo-random string. Not null terminated.
5210875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo// This does not gzip compress well.
53f68bbbc952aa9a71898e4939b5f36187fa564a50Alex Vakulenkoextern const uint8_t kRandomString[300];
5449fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
5549fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com// Writes the data passed to path. The file at path will be overwritten if it
5649fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com// exists. Returns true on success, false otherwise.
573f39d5cc753905874d8d93bef94f857b8808f19eAlex Vakulenkobool WriteFileVector(const std::string& path, const brillo::Blob& data);
58c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.combool WriteFileString(const std::string& path, const std::string& data);
5949fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
60c975d7bc6767711c4802e104c4a9d4731910c9beAlex Deymo// Binds provided |filename| to an unused loopback device, whose name is written
61c975d7bc6767711c4802e104c4a9d4731910c9beAlex Deymo// to the string pointed to by |out_lo_dev_name|. The new loop device will be
62c975d7bc6767711c4802e104c4a9d4731910c9beAlex Deymo// read-only unless |writable| is set to true. Returns true on success, false
63c975d7bc6767711c4802e104c4a9d4731910c9beAlex Deymo// otherwise (along with corresponding test failures), in which case the content
64c975d7bc6767711c4802e104c4a9d4731910c9beAlex Deymo// of |out_lo_dev_name| is unknown.
65c975d7bc6767711c4802e104c4a9d4731910c9beAlex Deymobool BindToUnusedLoopDevice(const std::string& filename,
66c975d7bc6767711c4802e104c4a9d4731910c9beAlex Deymo                            bool writable,
67c975d7bc6767711c4802e104c4a9d4731910c9beAlex Deymo                            std::string* out_lo_dev_name);
68c975d7bc6767711c4802e104c4a9d4731910c9beAlex Deymobool UnbindLoopDevice(const std::string& lo_dev_name);
69c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com
70c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com// Returns true iff a == b
713f39d5cc753905874d8d93bef94f857b8808f19eAlex Vakulenkobool ExpectVectorsEq(const brillo::Blob& a, const brillo::Blob& b);
72c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com
73c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.cominline int System(const std::string& cmd) {
74c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com  return system(cmd.c_str());
75c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com}
76c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com
772c2b884a4547407759e50681bb7bc49e3589d4feGilad Arnoldinline int Symlink(const std::string& oldpath, const std::string& newpath) {
782c2b884a4547407759e50681bb7bc49e3589d4feGilad Arnold  return symlink(oldpath.c_str(), newpath.c_str());
792c2b884a4547407759e50681bb7bc49e3589d4feGilad Arnold}
802c2b884a4547407759e50681bb7bc49e3589d4feGilad Arnold
812c2b884a4547407759e50681bb7bc49e3589d4feGilad Arnoldinline int Chmod(const std::string& path, mode_t mode) {
822c2b884a4547407759e50681bb7bc49e3589d4feGilad Arnold  return chmod(path.c_str(), mode);
832c2b884a4547407759e50681bb7bc49e3589d4feGilad Arnold}
842c2b884a4547407759e50681bb7bc49e3589d4feGilad Arnold
852c2b884a4547407759e50681bb7bc49e3589d4feGilad Arnoldinline int Mkdir(const std::string& path, mode_t mode) {
862c2b884a4547407759e50681bb7bc49e3589d4feGilad Arnold  return mkdir(path.c_str(), mode);
872c2b884a4547407759e50681bb7bc49e3589d4feGilad Arnold}
882c2b884a4547407759e50681bb7bc49e3589d4feGilad Arnold
8930dedd82be72ffa9bbe570e9c95166ec6bcc7792Gilad Arnoldinline int Chdir(const std::string& path) {
9030dedd82be72ffa9bbe570e9c95166ec6bcc7792Gilad Arnold  return chdir(path.c_str());
9130dedd82be72ffa9bbe570e9c95166ec6bcc7792Gilad Arnold}
9230dedd82be72ffa9bbe570e9c95166ec6bcc7792Gilad Arnold
93bb0c067bf37c98cc55b6c79c1174084b1e0c9b0bAlex Deymo// Reads a symlink from disk. Returns empty string on failure.
94bb0c067bf37c98cc55b6c79c1174084b1e0c9b0bAlex Deymostd::string Readlink(const std::string& path);
95bb0c067bf37c98cc55b6c79c1174084b1e0c9b0bAlex Deymo
9610875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo// Checks if xattr is supported in the directory specified by
9710875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo// |dir_path| which must be writable. Returns true if the feature is
98f68bbbc952aa9a71898e4939b5f36187fa564a50Alex Vakulenko// supported, false if not or if an error occurred.
9910875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymobool IsXAttrSupported(const base::FilePath& dir_path);
100c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com
1013f39d5cc753905874d8d93bef94f857b8808f19eAlex Vakulenkovoid FillWithData(brillo::Blob* buffer);
102c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com
1035c7d97590b51ae9e85dde1e37a3fd91d06f7991dThieu Le// Creates an empty ext image.
1045c7d97590b51ae9e85dde1e37a3fd91d06f7991dThieu Levoid CreateEmptyExtImageAtPath(const std::string& path,
1055c7d97590b51ae9e85dde1e37a3fd91d06f7991dThieu Le                               size_t size,
1065c7d97590b51ae9e85dde1e37a3fd91d06f7991dThieu Le                               int block_size);
1075c7d97590b51ae9e85dde1e37a3fd91d06f7991dThieu Le
108c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com// Creates an ext image with some files in it. The paths creates are
109c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com// returned in out_paths.
110c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.comvoid CreateExtImageAtPath(const std::string& path,
111c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com                          std::vector<std::string>* out_paths);
112c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com
11310875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo// Class to unmount FS when object goes out of scope
11410875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymoclass ScopedFilesystemUnmounter {
11510875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo public:
11610875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo  explicit ScopedFilesystemUnmounter(const std::string& mountpoint)
11710875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo      : mountpoint_(mountpoint),
11810875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo        should_unmount_(true) {}
11910875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo  ~ScopedFilesystemUnmounter() {
12010875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo    if (should_unmount_) {
12110875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo      utils::UnmountFilesystem(mountpoint_);
12210875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo    }
12310875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo  }
12410875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo  void set_should_unmount(bool unmount) { should_unmount_ = unmount; }
12510875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo private:
12610875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo  const std::string mountpoint_;
12710875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo  bool should_unmount_;
12810875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo  DISALLOW_COPY_AND_ASSIGN(ScopedFilesystemUnmounter);
12910875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo};
13010875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo
13158e8b1f8b32b355d879008572648fd621873711dDon Garrettclass ScopedLoopbackDeviceBinder {
13209e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes public:
133c975d7bc6767711c4802e104c4a9d4731910c9beAlex Deymo  ScopedLoopbackDeviceBinder(const std::string& file,
134c975d7bc6767711c4802e104c4a9d4731910c9beAlex Deymo                             bool writable,
135c975d7bc6767711c4802e104c4a9d4731910c9beAlex Deymo                             std::string* dev) {
136c975d7bc6767711c4802e104c4a9d4731910c9beAlex Deymo    is_bound_ = BindToUnusedLoopDevice(file, writable, &dev_);
13719a45f0eda0917b7788b925b501e774208474fdeGilad Arnold    EXPECT_TRUE(is_bound_);
13858e8b1f8b32b355d879008572648fd621873711dDon Garrett
13919a45f0eda0917b7788b925b501e774208474fdeGilad Arnold    if (is_bound_ && dev)
14058e8b1f8b32b355d879008572648fd621873711dDon Garrett      *dev = dev_;
14158e8b1f8b32b355d879008572648fd621873711dDon Garrett  }
14258e8b1f8b32b355d879008572648fd621873711dDon Garrett
14358e8b1f8b32b355d879008572648fd621873711dDon Garrett  ~ScopedLoopbackDeviceBinder() {
14419a45f0eda0917b7788b925b501e774208474fdeGilad Arnold    if (!is_bound_)
14519a45f0eda0917b7788b925b501e774208474fdeGilad Arnold      return;
14619a45f0eda0917b7788b925b501e774208474fdeGilad Arnold
147cf56248d8b176c1ba024a7040067bdde18112beaDarin Petkov    for (int retry = 0; retry < 5; retry++) {
148c975d7bc6767711c4802e104c4a9d4731910c9beAlex Deymo      if (UnbindLoopDevice(dev_))
149cf56248d8b176c1ba024a7040067bdde18112beaDarin Petkov        return;
150cf56248d8b176c1ba024a7040067bdde18112beaDarin Petkov      sleep(1);
151cf56248d8b176c1ba024a7040067bdde18112beaDarin Petkov    }
152cf56248d8b176c1ba024a7040067bdde18112beaDarin Petkov    ADD_FAILURE();
15309e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes  }
15458e8b1f8b32b355d879008572648fd621873711dDon Garrett
15519a45f0eda0917b7788b925b501e774208474fdeGilad Arnold  const std::string &dev() {
15619a45f0eda0917b7788b925b501e774208474fdeGilad Arnold    EXPECT_TRUE(is_bound_);
15719a45f0eda0917b7788b925b501e774208474fdeGilad Arnold    return dev_;
15819a45f0eda0917b7788b925b501e774208474fdeGilad Arnold  }
15958e8b1f8b32b355d879008572648fd621873711dDon Garrett
160c33faebbd0b26cedb7ef51889c405cf85d79be0cGilad Arnold  bool is_bound() const { return is_bound_; }
161c33faebbd0b26cedb7ef51889c405cf85d79be0cGilad Arnold
16209e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes private:
16358e8b1f8b32b355d879008572648fd621873711dDon Garrett  std::string dev_;
16419a45f0eda0917b7788b925b501e774208474fdeGilad Arnold  bool is_bound_;
16558e8b1f8b32b355d879008572648fd621873711dDon Garrett  DISALLOW_COPY_AND_ASSIGN(ScopedLoopbackDeviceBinder);
16609e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes};
16709e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes
168f9185170a9763e493e77ffdc5b1f057c3bd3b11eAndrew de los Reyesclass ScopedTempFile {
169f9185170a9763e493e77ffdc5b1f057c3bd3b11eAndrew de los Reyes public:
170bffa06080ec8bd5d196cbfadf2023f78b6e89169Alex Deymo  ScopedTempFile() : ScopedTempFile("update_engine_test_temp_file.XXXXXX") {}
171bffa06080ec8bd5d196cbfadf2023f78b6e89169Alex Deymo
172bffa06080ec8bd5d196cbfadf2023f78b6e89169Alex Deymo  explicit ScopedTempFile(const std::string& pattern) {
173bffa06080ec8bd5d196cbfadf2023f78b6e89169Alex Deymo    EXPECT_TRUE(utils::MakeTempFile(pattern, &path_, nullptr));
174f9185170a9763e493e77ffdc5b1f057c3bd3b11eAndrew de los Reyes    unlinker_.reset(new ScopedPathUnlinker(path_));
175f9185170a9763e493e77ffdc5b1f057c3bd3b11eAndrew de los Reyes  }
176bffa06080ec8bd5d196cbfadf2023f78b6e89169Alex Deymo
177bffa06080ec8bd5d196cbfadf2023f78b6e89169Alex Deymo  const std::string& path() { return path_; }
178bffa06080ec8bd5d196cbfadf2023f78b6e89169Alex Deymo
179f9185170a9763e493e77ffdc5b1f057c3bd3b11eAndrew de los Reyes private:
180f9185170a9763e493e77ffdc5b1f057c3bd3b11eAndrew de los Reyes  std::string path_;
18102f7c1dee242f490143791dbb73fa23fa3007cfaBen Chan  std::unique_ptr<ScopedPathUnlinker> unlinker_;
182f9185170a9763e493e77ffdc5b1f057c3bd3b11eAndrew de los Reyes};
183f9185170a9763e493e77ffdc5b1f057c3bd3b11eAndrew de los Reyes
18410875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymoclass ScopedLoopMounter {
18510875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo public:
18610875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo  explicit ScopedLoopMounter(const std::string& file_path,
18710875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo                             std::string* mnt_path,
18810875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo                             unsigned long flags);  // NOLINT(runtime/int)
18910875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo
19010875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo private:
19110875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo  // These objects must be destructed in the following order:
19210875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo  //   ScopedFilesystemUnmounter (the file system must be unmounted first)
19310875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo  //   ScopedLoopbackDeviceBinder (then the loop device can be deleted)
19410875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo  //   ScopedDirRemover (then the mount point can be deleted)
19510875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo  std::unique_ptr<ScopedDirRemover> dir_remover_;
19610875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo  std::unique_ptr<ScopedLoopbackDeviceBinder> loop_binder_;
19710875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo  std::unique_ptr<ScopedFilesystemUnmounter> unmounter_;
19810875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo};
19910875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo
2002b19cfbcdb1aa8c5d1f338d19312fe14b6734bd5Alex Deymo// Returns the path where the build artifacts are stored. This is the directory
2012b19cfbcdb1aa8c5d1f338d19312fe14b6734bd5Alex Deymo// where the unittest executable is being run from.
2022b19cfbcdb1aa8c5d1f338d19312fe14b6734bd5Alex Deymobase::FilePath GetBuildArtifactsPath();
20310875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo
2042b19cfbcdb1aa8c5d1f338d19312fe14b6734bd5Alex Deymo}  // namespace test_utils
20510875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo
20610875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo// Useful actions for test. These need to be defined in the
20710875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo// chromeos_update_engine namespace.
208c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com
209c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.comclass NoneType;
210c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com
211c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.comtemplate<typename T>
212c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.comclass ObjectFeederAction;
213c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com
214c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.comtemplate<typename T>
215f9cb98c0cacccca803db48502c7bd461d04cb6b0Ben Chanclass ActionTraits<ObjectFeederAction<T>> {
216c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com public:
217c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com  typedef T OutputObjectType;
218c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com  typedef NoneType InputObjectType;
219c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com};
220c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com
221c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com// This is a simple Action class for testing. It feeds an object into
222c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com// another action.
223c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.comtemplate<typename T>
224f9cb98c0cacccca803db48502c7bd461d04cb6b0Ben Chanclass ObjectFeederAction : public Action<ObjectFeederAction<T>> {
225c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com public:
226c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com  typedef NoneType InputObjectType;
227c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com  typedef T OutputObjectType;
228c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com  void PerformAction() {
229c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com    LOG(INFO) << "feeder running!";
230c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com    CHECK(this->processor_);
231c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com    if (this->HasOutputPipe()) {
232c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com      this->SetOutputObject(out_obj_);
233c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com    }
234d1c4d2dd3daed1d507038046c0355fbafb85260cGilad Arnold    this->processor_->ActionComplete(this, ErrorCode::kSuccess);
235c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com  }
236c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com  static std::string StaticType() { return "ObjectFeederAction"; }
237c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com  std::string Type() const { return StaticType(); }
238c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com  void set_obj(const T& out_obj) {
239c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com    out_obj_ = out_obj;
240c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com  }
241c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com private:
242c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com  T out_obj_;
243c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com};
244c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com
245c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.comtemplate<typename T>
246c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.comclass ObjectCollectorAction;
247c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com
248c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.comtemplate<typename T>
249f9cb98c0cacccca803db48502c7bd461d04cb6b0Ben Chanclass ActionTraits<ObjectCollectorAction<T>> {
250c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com public:
251c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com  typedef NoneType OutputObjectType;
252c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com  typedef T InputObjectType;
253c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com};
254c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com
255c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com// This is a simple Action class for testing. It receives an object from
256c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com// another action.
257c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.comtemplate<typename T>
258f9cb98c0cacccca803db48502c7bd461d04cb6b0Ben Chanclass ObjectCollectorAction : public Action<ObjectCollectorAction<T>> {
259c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com public:
260c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com  typedef T InputObjectType;
261c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com  typedef NoneType OutputObjectType;
262c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com  void PerformAction() {
263c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com    LOG(INFO) << "collector running!";
264c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com    ASSERT_TRUE(this->processor_);
265c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com    if (this->HasInputObject()) {
266c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com      object_ = this->GetInputObject();
267c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com    }
268d1c4d2dd3daed1d507038046c0355fbafb85260cGilad Arnold    this->processor_->ActionComplete(this, ErrorCode::kSuccess);
269c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com  }
270c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com  static std::string StaticType() { return "ObjectCollectorAction"; }
271c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com  std::string Type() const { return StaticType(); }
272c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com  const T& object() const { return object_; }
273c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com private:
274c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com  T object_;
275c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com};
276c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com
27749fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com}  // namespace chromeos_update_engine
27849fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
27939910dcd1d68987ccee7c3031dc269233a8490bbAlex Deymo#endif  // UPDATE_ENGINE_COMMON_TEST_UTILS_H_
280