text:
/*
// Copyright (c) 2000-2009, Texas Engineering Experiment Station (TEES), a
// component of the Texas A&M University System.

// All rights reserved.

// The information and source code contained herein is the exclusive
// property of TEES and may not be disclosed, examined or reproduced
// in whole or in part without explicit written authorization from TEES.
*/

#ifndef STAPL_PARAGRAPH_EDGE_LOCAL_NOTIFIER_HPP
#define STAPL_PARAGRAPH_EDGE_LOCAL_NOTIFIER_HPP

#include <boost/intrusive_ptr.hpp>

namespace stapl {

namespace detail {

using paragraph_impl::task_base;

//////////////////////////////////////////////////////////////////////
/// @brief Represents the primary interface through which users of
///   the @ref edge_container or @ref edge_view (i.e., @p task_graph) are
///   informed of data flow events triggered by the completion of predecessor
///    tasks.
/// @ingroup pgEdgeNotifiers
///
/// Instances of this class are heap allocated and passed to the
/// @ref edge_container when successor tasks create an edge via
/// @ref edge_view::setup_flow.  When data flow is available for a successor,
/// the @p edge_container will invoke this object's function operator, once
/// per specified predecessor.  When all notifications have been received,
/// this object passes the successor task to the PARAGRAPH's executor, making it
/// eligible for execution.
///
/// Note that the interface to access the value facilitated through a
/// different interface, namely @ref edge_view::operator[].
///
/// @sa edge_view::setup_flow
/// @sa edge_view::operator[]
/// @sa aggregated_edge_view::setup_flow
/// @sa aggregated_edge_view::operator[]
/// @sa executor_base
//////////////////////////////////////////////////////////////////////
struct edge_local_notifier_base
{
protected:
  /// @brief Denotes whether PARAGRAPH this edge notifier is a part of is
  /// persistent.
  const bool m_b_persistent;

public:
  typedef void result_type;

  edge_local_notifier_base(bool persistent)
    : m_b_persistent(persistent)
  { }

  virtual ~edge_local_notifier_base(void) = default;

  //////////////////////////////////////////////////////////////////////
  /// @brief Invoked by each predecessor edge which this notifier was registered
  /// with, signifying that the value is now available for consumption.  When
  /// the @p operator() has been called by all predecessors, the task associated
  /// with the notifier (@p m_task_ptr) is released to the @p executor as
  /// runnable.
  //////////////////////////////////////////////////////////////////////
  virtual void operator()(executor_base&) = 0;

  //////////////////////////////////////////////////////////////////////
  /// @brief Set the internal pointer to the task associated with this notifier
  /// so that it can be passed to the executor when all edge trigger events
  /// (i.e., operator() calls) have occurred.
  ///
  /// @param t        Pointer to task associated with this predecessor notifier.
  /// @param executor The executor associated with the PARAGRAPH for this
  ///                 notifier.
  ///
  /// Initialization of the task happens concurrently with the construction of
  /// this object and the edge creations it participates in.  When
  /// @p task_graph_impl::add_task finishes creating the task, it calls
  /// this method.
  ///
  /// @sa task_graph_impl::add_task
  //////////////////////////////////////////////////////////////////////
  virtual void set_task_ptr(task_base* t, executor_base& executor) = 0;

  //////////////////////////////////////////////////////////////////////
  /// @brief Freestanding function required for boost::intrusive_ptr, which is
  /// used to implement reference counting on this object, as needed for
  /// persistent PARAGRAPH usage.
  ///
  /// @param ptr An instance of @p edge_local_notifier_base who reference count
  /// is to be incremented.
  //////////////////////////////////////////////////////////////////////
  friend
  void intrusive_ptr_add_ref(edge_local_notifier_base const* ptr)
  {
    ptr->intrusive_ptr_add_ref_impl();
  }

  //////////////////////////////////////////////////////////////////////
  /// @brief Freestanding function required for boost::intrusive_ptr, which is
  /// used to implement reference counting on this object, as needed for
  /// persistent PARAGRAPH usage.
  ///
  /// @param ptr An instance of @p edge_local_notifier_base who reference count
  ///   is to be decremented.
  //////////////////////////////////////////////////////////////////////
  friend
  void intrusive_ptr_release(edge_local_notifier_base const* ptr)
  {
    ptr->intrusive_ptr_release_impl();
  }

  //////////////////////////////////////////////////////////////////////
  /// @brief Pure virtual method that defines interface for implementation of
  /// counter increment called by @p freestanding @ref intrusive_ptr_add_ref.
  /// Implemented in @ref edge_local_notifier.
  //////////////////////////////////////////////////////////////////////
  virtual void intrusive_ptr_add_ref_impl(void) const = 0;

  //////////////////////////////////////////////////////////////////////
  /// @brief Pure virtual method that defines interface for implementation of
  /// counter decrement called by freestanding @ref intrusive_ptr_release.
  /// Implemented in @ref edge_local_notifier.
  //////////////////////////////////////////////////////////////////////
  virtual void intrusive_ptr_release_impl(void) const = 0;
};

//////////////////////////////////////////////////////////////////////
/// @brief Derived class of @p edge_local_notifier_base that holds notifier
///   counters, associated task and metadata for scheduling.  Type is erased
///   immediately after construction in @ref task_graph_impl::add_task.
/// @ingroup pgEdgeNotifiers
///
/// @todo Track down why @p m_ref_count is mutable.  Probably tied to
/// overly conservative const qualification of notifiers in the
/// @p edge_container.
//////////////////////////////////////////////////////////////////////
struct edge_local_notifier
  : public edge_local_notifier_base
{
private:
  /// @brief The count of outstanding predecessor notifications for this
  /// execution of the PARAGRAPH.
  std::size_t          m_pred_count;

  /// @brief Pointer to the task this notifier should make runnable when all
  /// predecessors have triggered data flow.
  task_base*           m_task_ptr;

  /// @brief The in-degree of the associated task in the PARAGRAPH. Used to
  /// reinitialize m_pred_count when persistent reexecution enabled.
  const std::size_t    m_init_count;

  /// @brief Used to track the number of predecessor @p edge_entry notifier list
  /// that have a reference to this object.  Used for lifetime management when
  /// used in a persistent PARAGRAPH (Otherwise, deletion in operator()).
  mutable std::size_t  m_ref_count;

  edge_local_notifier(edge_local_notifier const&) = delete;
  edge_local_notifier& operator=(edge_local_notifier const&) = delete;

public:
  explicit
  edge_local_notifier(std::size_t pred_count, bool persistent)
    : edge_local_notifier_base(persistent),
      m_pred_count(pred_count),
      m_task_ptr(nullptr),
      m_init_count(pred_count),
      m_ref_count(0)
  { }

  ~edge_local_notifier() final
  {
    if (m_b_persistent)
    {
      delete m_task_ptr;
    }
  }

  STAPL_USE_MANAGED_ALLOC(edge_local_notifier)

  //////////////////////////////////////////////////////////////////////
  /// @brief Implementation of pure virtual method defined in abstract base
  /// class @p edge_local_notifier.
  ///
  /// Increment reference count and check
  /// assertions context on which method was called.
  ///
  /// @sa edge_local_notifier::intrusive_ptr_add_ref_impl
  //////////////////////////////////////////////////////////////////////
  void intrusive_ptr_add_ref_impl(void) const final
  {
    stapl_assert(m_b_persistent,
      "Intrusive add_ref called when not persistent");

    ++m_ref_count;
  }

  //////////////////////////////////////////////////////////////////////
  /// @brief Implementation of pure virtual method defined in abstract base
  /// class @p edge_local_notifier.
  ///
  /// Decrement reference count and check
  /// assertions context on which method was called.
  ///
  /// @sa edge_local_notifier::intrusive_ptr_release_impl
  //////////////////////////////////////////////////////////////////////
  void intrusive_ptr_release_impl(void) const final
  {
    stapl_assert(m_b_persistent,
      "Intrusive release called when not persistent");

    if (--m_ref_count == 0)
    {
      stapl_assert(m_pred_count == m_init_count,
        "Unexpected m_pred_count in ptr_release");

      delete this;
    }
  }

  //////////////////////////////////////////////////////////////////////
  /// @brief Implementation of pure virtual method defined in abstract base
  /// class @p edge_local_notifier.
  ///
  /// @sa edge_local_notifier::operator()
  //////////////////////////////////////////////////////////////////////
  void operator()(executor_base& executor) final
  {
    stapl_assert(m_pred_count,
      "edge_local_notifier::operator(): invoked with m_pred_count == 0");

    // m_task_ptr isn't set until the the task is fully constructed and
    // all predecessor info is initialized.  If pred_count is reduced to
    // 0 before m_task_ptr is set, it will be added to the executor in
    // set_task_ptr (below) when invoked at the end tg:add_task()
    if ((--m_pred_count == 0) && (m_task_ptr != nullptr))
    {
      executor.add_task(m_task_ptr);

      /// reset if persistent, otherwise self destruct.
      if (this->m_b_persistent)
        m_pred_count = m_init_count;
      else
      {
        delete this;
      }
    }
  }

  //////////////////////////////////////////////////////////////////////
  /// @brief Implementation of pure virtual method defined in abstract base
  /// class @p edge_local_notifier.
  ///
  /// @sa edge_local_notifier::set_task_ptr
  //////////////////////////////////////////////////////////////////////
  void set_task_ptr(task_base* t, executor_base& executor) final
  {
    m_task_ptr = t;

    // I'm trying to catch underflow and wrap around to large size_t values
    // This assume< 5000 view parameters to a workfunction :)
    //
    stapl_assert(m_pred_count <= 5000,
      "edge_local_notifier::set_task_ptr: found m_pred_count underflow");

    // I still have outstanding preds.  Subsequent calls to operator()
    // will decrement count and eventually make me runnable.
    //
    if (m_pred_count > 0)
      return;

    // else...
    //
    // I had preds, otherwise this edge_local_notifier object wouldn't have
    // been created. However, they have finished and notified me during task
    // initialization (i.e., in tg::add_task() between
    // edge_local_notifier::edge_local_notifier(...) and this call). notify
    // executor task is runnable and kill myself.
    //
    executor.add_task(m_task_ptr);

    if (this->m_b_persistent)
      m_pred_count = m_init_count;
    else
      delete this;

  }
}; // struct edge_local_notifier

} // namespace detail

} // namespace stapl

#endif // ifndef STAPL_PARAGRAPH_EDGE_LOCAL_NOTIFIER_HPP


text:
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright David Abrahams, Vicente Botet, Ion Gaztanaga 2009.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/move for documentation.
//
//////////////////////////////////////////////////////////////////////////////

//[construct_forward_example
#include <boost/move/move.hpp>
#include <iostream>

class copyable_only_tester
{
   public:
   copyable_only_tester()
   {  std::cout << "copyable_only_tester()" << std::endl;   }

   copyable_only_tester(const copyable_only_tester&)
   {  std::cout << "copyable_only_tester(const copyable_only_tester&)" << std::endl;   }

   copyable_only_tester(int)
   {  std::cout << "copyable_only_tester(int)" << std::endl;   }

   copyable_only_tester(int, double)
   {  std::cout << "copyable_only_tester(int, double)" << std::endl;   }
};

class copyable_movable_tester
{
   // move semantics
   BOOST_COPYABLE_AND_MOVABLE(copyable_movable_tester)
   public:

   copyable_movable_tester()
   {  std::cout << "copyable_movable_tester()" << std::endl;   }

   copyable_movable_tester(int)
   {  std::cout << "copyable_movable_tester(int)" << std::endl;   }

   copyable_movable_tester(BOOST_RV_REF(copyable_movable_tester))
   {  std::cout << "copyable_movable_tester(BOOST_RV_REF(copyable_movable_tester))" << std::endl;   }

   copyable_movable_tester(const copyable_movable_tester &)
   {  std::cout << "copyable_movable_tester(const copyable_movable_tester &)" << std::endl;   }

   copyable_movable_tester(BOOST_RV_REF(copyable_movable_tester), BOOST_RV_REF(copyable_movable_tester))
   {  std::cout << "copyable_movable_tester(BOOST_RV_REF(copyable_movable_tester), BOOST_RV_REF(copyable_movable_tester))" << std::endl;   }

   copyable_movable_tester &operator=(BOOST_RV_REF(copyable_movable_tester))
   {  std::cout << "copyable_movable_tester & operator=(BOOST_RV_REF(copyable_movable_tester))" << std::endl;
      return *this;  }

   copyable_movable_tester &operator=(BOOST_COPY_ASSIGN_REF(copyable_movable_tester))
   {  std::cout << "copyable_movable_tester & operator=(BOOST_COPY_ASSIGN_REF(copyable_movable_tester))" << std::endl;
      return *this;  }
};

//1 argument
template<class MaybeMovable, class MaybeRv>
void function_construct(BOOST_FWD_REF(MaybeRv) x)
{  MaybeMovable m(boost::forward<MaybeRv>(x));   }

//2 argument
template<class MaybeMovable, class MaybeRv, class MaybeRv2>
void function_construct(BOOST_FWD_REF(MaybeRv) x, BOOST_FWD_REF(MaybeRv2) x2)
{  MaybeMovable m(boost::forward<MaybeRv>(x), boost::forward<MaybeRv2>(x2));  }

int main()
{
   copyable_movable_tester m;
   //move constructor
   function_construct<copyable_movable_tester>(boost::move(m));
   //copy constructor
   function_construct<copyable_movable_tester>(copyable_movable_tester());
   //two rvalue constructor
   function_construct<copyable_movable_tester>(boost::move(m), boost::move(m));

   copyable_only_tester nm;
   //copy constructor (copyable_only_tester has no move ctor.)
   function_construct<copyable_only_tester>(boost::move(nm));
   //copy constructor
   function_construct<copyable_only_tester>(nm);
   //int constructor
   function_construct<copyable_only_tester>(int(0));
   //int, double constructor
   function_construct<copyable_only_tester>(int(0), double(0.0));

   //Output is:
   //copyable_movable_tester()
   //copyable_movable_tester(BOOST_RV_REF(copyable_movable_tester))
   //copyable_movable_tester()
   //copyable_movable_tester(const copyable_movable_tester &)
   //copyable_movable_tester(BOOST_RV_REF(copyable_movable_tester), BOOST_RV_REF(copyable_movable_tester))
   //copyable_only_tester()
   //copyable_only_tester(const copyable_only_tester&)
   //copyable_only_tester(const copyable_only_tester&)
   //copyable_only_tester(int)
   //copyable_only_tester(int, double)
   return 0;
}
//]

ext: cpp

max_stars_repo_name: randolphwong/mcsema

max_issues_repo_name: randolphwong/mcsema

max_forks_repo_name: randolphwong/mcsema


text:
//
//  PasswordController.hpp
//  MyMonero
//
//  Copyright (c) 2014-2019, MyMonero.com
//
//  All rights reserved.
//
//  Redistribution and use in source and binary forms, with or without modification, are
//  permitted provided that the following conditions are met:
//
//  1. Redistributions of source code must retain the above copyright notice, this list of
//	conditions and the following disclaimer.
//
//  2. Redistributions in binary form must reproduce the above copyright notice, this list
//	of conditions and the following disclaimer in the documentation and/or other
//	materials provided with the distribution.
//
//  3. Neither the name of the copyright holder nor the names of its contributors may be
//	used to endorse or promote products derived from this software without specific
//	prior written permission.
//
//  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
//  EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
//  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
//  THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
//  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
//  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
//  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
//  STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
//  THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
//

#ifndef PasswordController_hpp
#define PasswordController_hpp

#include <string>
#include <boost/range/algorithm.hpp>
#include <boost/optional/optional.hpp>
#include <boost/signals2.hpp>
#include <memory>
#include "../Persistence/document_persister.hpp"
#include "../Dispatch/Dispatch_Interface.hpp"
#include "../UserIdle/UserIdle.hpp"

namespace Passwords
{
	using namespace std;
	//
	typedef string Password;
}
namespace Passwords
{
	using namespace std;
	//
	enum Type
	{ // These are given specific values for the purpose of serialization through the app lib bridge and more critically for persistence, so they should not be changed
		minBound = -1,
		//
		PIN = 0,
		password = 1,
		//
		maxBound = 2
	};
	//
	static inline std::string new_humanReadableString(Type type)
	{ // TODO: this will probably need to be localized at the application layer anyway
		return std::string(
			type == PIN ? "PIN" : "password" // TODO: return localized
		);
	}
	static inline std::string capitalized_humanReadableString(Type type)
	{ // TODO: this will probably need to be localized at the application layer anyway
		std::string str = new_humanReadableString(type);
		str[0] = (char)toupper(str[0]);
		//
		return str;
	}
	static inline std::string new_invalidEntry_humanReadableString(Type type) // TOOD: return localized
	{ // TODO: maybe just keep this function at the Android level so it can be localized .. or maybe better to ship localizations with app lib so they're not duplicated everywhere? haven't confirmed C++ lib best practice yet
		return type == PIN ? "Incorrect PIN" : "Incorrect password";
	}
	static inline Type new_detectedFromPassword(Password &password)
	{
		std::string copyOf_password = password;
		copyOf_password.erase(boost::remove_if(copyOf_password, ::isdigit), copyOf_password.end());

		return copyOf_password.empty() ? Type::PIN : Type::password;
	}
}
namespace Passwords
{
	class PasswordControllerEventParticipant
	{ // abstract interface - implement with another interface
	public:
		virtual ~PasswordControllerEventParticipant() {}
		//
		virtual std::string identifier() const = 0; // To support isEqual, ==
		bool operator==(PasswordControllerEventParticipant const &rhs) const
		{
			return identifier() == rhs.identifier();
		}
		bool operator!=(PasswordControllerEventParticipant const &rhs) const
		{
			return (*this == rhs) == false;
		}
	};
}
namespace Passwords
{
	using namespace std;
	using namespace boost;
	//
	class PasswordEntryDelegate : public PasswordControllerEventParticipant
	{
	public:
		virtual ~PasswordEntryDelegate() {}
		//
		virtual void getUserToEnterExistingPassword(
			bool isForChangePassword,
			bool isForAuthorizingAppActionOnly, // normally no - this is for things like SendFunds
			optional<string> customNavigationBarTitle
		) = 0;
		// then call Controller::enterExistingPassword_cb
		//
		virtual void getUserToEnterNewPasswordAndType(
			bool isForChangePassword
		) = 0;
		// then call Controller::enterNewPasswordAndType_cb
	};
}
namespace Passwords
{ // Constants
	static const uint32_t minPasswordLength = 6;
	static const uint32_t maxLegal_numberOfTriesDuringThisTimePeriod = 5;
	static const size_t pwEntrySpamming_unlockInT_s = 10;
	static const size_t pwEntrySpamming_unlockInT_ms = pwEntrySpamming_unlockInT_s * 1000;
	//
	enum EnterPW_Fn_ValidationErr_Code
	{
		pleaseWaitBeforeTryingAgain = 0,
		incorrectPassword = 1,
		enterLongerPIN = 2,
		enterLongerPassword = 3,
		unrecognizedPasswordType = 4,
		enterFreshPIN = 5,
		enterFreshPassword = 6,
		saveError = 7,
		changePasswordError = 8,
		clearValidationErrorAndAllowRetry = 9,
		notBootedYet = 10,
		unexpectedState = 11
	};
}
namespace Passwords
{
	using namespace std;
	using namespace boost;
	//
	class ChangePasswordRegistrant: public PasswordControllerEventParticipant
	{ // Implement this function to support change-password events as well as revert-from-failed-change-password
	public:
		virtual optional<EnterPW_Fn_ValidationErr_Code> passwordController_ChangePassword() = 0; // return err_str:String if error - it will abort and try to revert the changepassword process. at time of writing, this was able to be kept synchronous.
		// TODO: ^-- maybe make this return a code instead of an error string
	};
	class DeleteEverythingRegistrant: public PasswordControllerEventParticipant
	{
	public:
		virtual optional<string> passwordController_DeleteEverything() = 0; // return err_str:String if error. at time of writing, this was able to be kept synchronous.
		// TODO: ^-- maybe make this return a code instead of an error string
	};
}
namespace Passwords
{
	using namespace std;
	using namespace boost;
	using namespace document_persister;
	//
	// Interfaces
	class PasswordProvider
	{ // you can use this type for dependency-injecting a Passwords::Controller implementation; see PersistableObject
	public:
		virtual ~PasswordProvider() {}
		virtual boost::optional<Password> getPassword() const = 0;
	};
	//
	// Controllers
	class Controller: public PasswordProvider, public std::enable_shared_from_this<Controller>
	{
	public:
		//
		// Lifecycle - Init
		Controller() {
			// set dependencies then call setup()
		}
		Controller(const Controller&) = delete; // disable copy constructor to prevent inadvertent temporary in pointer
		Controller& operator=(const Controller&) = delete;
		~Controller() {
			cout << "Destructing a Passwords::Controller" << endl;
			teardown();
		}
		//
		// Dependencies
		std::shared_ptr<string> documentsPath;
		std::shared_ptr<Dispatch::Dispatch> dispatch_ptr;
		std::shared_ptr<UserIdle::Controller> userIdleController;
		// Then call:
		void setup();
		//
		// Signals
		boost::signals2::signal<void()> obtainedNewPassword_signal;
		boost::signals2::signal<void()> obtainedCorrectExistingPassword_signal;
		//
		boost::signals2::signal<void(EnterPW_Fn_ValidationErr_Code code)> erroredWhileGettingExistingPassword_signal;
		boost::signals2::signal<void(EnterPW_Fn_ValidationErr_Code code)> erroredWhileSettingNewPassword_signal;
		boost::signals2::signal<void()> canceledWhileEnteringExistingPassword_signal;
		boost::signals2::signal<void()> canceledWhileEnteringNewPassword_signal;
		//
		boost::signals2::signal<void()> setFirstPasswordDuringThisRuntime_signal;
		boost::signals2::signal<void()> registrantsAllChangedPassword_signal;
		//
		boost::signals2::signal<void()> canceledWhileChangingPassword_signal;
		boost::signals2::signal<void(EnterPW_Fn_ValidationErr_Code code)> errorWhileChangingPassword_signal;
		//
		boost::signals2::signal<void()> duringAuthentication_tryBiometrics_signal;
		boost::signals2::signal<void(EnterPW_Fn_ValidationErr_Code code)> errorWhileAuthorizingForAppAction_signal;
		boost::signals2::signal<void()> successfullyAuthenticatedForAppAction_signal;
		//
		boost::signals2::signal<void(bool isForADeleteEverything)> willDeconstructBootedStateAndClearPassword_signal;
		boost::signals2::signal<void()> didDeconstructBootedStateAndClearPassword_signal;
		boost::signals2::signal<void()> havingDeletedEverything_didDeconstructBootedStateAndClearPassword_signal;
		//
		// Accessors - Interfaces - PasswordProvider
		optional<Password> getPassword() const;
		// Accessors - Members
		Passwords::Type getPasswordType() const;
		// Accessors - Persistence state
		bool hasUserSavedAPassword() const;
		//
		// Accessors - Derived properties
		bool hasUserEnteredValidPasswordYet() const;
		bool isUserChangingPassword() const;
		//
		// Imperatives - PasswordEntryDelegate
		void setPasswordEntryDelegate(PasswordEntryDelegate &to_delegate);
		void clearPasswordEntryDelegate(PasswordEntryDelegate &from_existing_delegate);
		//
		void TEST_resetPasswordControllerInitAndObservers();
		void TEST_clearUnlockTimer();
		void TEST_bypassCheckAndClear_passwordEntryDelegate();
		//
		// Imperatives - Execution Deferment
		void onceBooted(std::function<void()> fn);
		//
		void onceBootedAndPasswordObtained(
			std::function<void(Password password, Passwords::Type passwordType)>&& fn,
			std::function<void()> userCanceled_fn
		);
		//
		void addRegistrantForChangePassword(ChangePasswordRegistrant &registrant);
		void removeRegistrantForChangePassword(ChangePasswordRegistrant &registrant);
		void initiate_changePassword();
		//
		void addRegistrantForDeleteEverything(DeleteEverythingRegistrant &registrant);
		void removeRegistrantForDeleteEverything(DeleteEverythingRegistrant &registrant);
		void initiateDeleteEverything();
		//
		void lockDownAppAndRequirePassword();
		//
		// Imperatives - Password entry attempt callbacks - to be called by the PasswordEntryDelegate
		void enterExistingPassword_cb( // this will throw an exception if called while the controller is not waiting for it
			boost::optional<bool> didCancel,
			boost::optional<Password> obtainedPasswordString
		);
		void enterNewPasswordAndType_cb( // this will throw an exception if called while the controller is not waiting for it
			boost::optional<bool> didCancel,
			boost::optional<Password> obtainedPasswordString,
			boost::optional<Type> userSelectedTypeOfPassword
		);
		//
		void initiate_verifyUserAuthenticationForAction(
			bool tryBiometrics,
			optional<string> customNavigationBarTitle_orNone,
			std::function<void()> canceled_fn,
			std::function<void()> entryAttempt_succeeded_fn // required
		);
		void authenticationCB_biometricsSucceeded();
		void authenticationCB_biometricsFailed();
		void authenticationCB_biometricsUnavailable();
		void authenticationCB_biometricsCanceled();
		//
	private:
		//
		// Properties - Instance members
		bool hasBooted = false;
		optional<DocumentId> _id = none;
		optional<Password> _password = none;
		Passwords::Type _passwordType;
		boost::optional<string> _messageAsEncryptedDataForUnlockChallenge_base64String = none;
		boost::optional<bool> _isAlreadyGettingExistingOrNewPWFromUser = none;
		//
		bool _preexistingBeforeSetNew_wasFirstSetOfPasswordAtRuntime;
		optional<Password> _preexistingBeforeSetNew_password = none;
		Passwords::Type _preexistingBeforeSetNew_passwordType;
		bool _preexistingBeforeSetNew_isForChangePassword;
		//
		void _callAndFlushAllBlocksWaitingForBootToExecute();
		optional<vector<std::function<void()>>> __blocksWaitingForBootToExecute = none;
		// NOTE: onceBooted() exists because even though init()->setup() is synchronous, we need to be able to tear down and reconstruct the passwordController booted state, e.g. on user idle and delete everything
		//
		Passwords::PasswordEntryDelegate *_passwordEntryDelegate = nullptr; // someone in the app must set this by calling setPasswordEntryDelegate()
		//
		bool isWaitingFor_enterExistingPassword_cb = false;
		optional<std::function<void(
			optional<bool> didCancel_orNone,
			optional<EnterPW_Fn_ValidationErr_Code> validationErr_orNone,
			optional<Password> obtainedPasswordString
		)>> enterExistingPassword_final_fn = none;
		bool _isCurrentlyLockedOutFromPWEntryAttempts = false;
		size_t _numberOfTriesDuringThisTimePeriod = 0;
		optional<time_t> _dateOf_firstPWTryDuringThisTimePeriod;
		std::unique_ptr<Dispatch::CancelableTimerHandle> _pw_entry_unlock_timer_handle; // initialized to nullptr
		bool isWaitingFor_enterNewPassword_cb = false;
		//
		// Authentication
		optional<string> _waitingForAuth_customNavigationBarTitle_orNone;
		optional<std::function<void()>> _waitingForAuth_canceled_fn;
		optional<std::function<void()>> _waitingForAuth_entryAttempt_succeeded_fn;
		void _proceedTo_authenticateVia_passphrase();
		void _authentication__callBackWithEntryAttempt_succeeded();
		void _authentication__callBackWithEntryAttempt_canceled();
		//
		// Accessors
		bool withExistingPassword_isCorrect(const string &enteredPassword) const;
		//
		// Imperatives
		void teardown();
		void startObserving();
		void initializeRuntimeAndBoot();
		void _proceedTo_load(const DocumentJSON &documentJSON);
		// Imperatives - Persistence
		optional<string>/*err_str*/ saveToDisk();
		//
		void givenBooted_initiateGetNewOrExistingPasswordFromUserAndEmitIt();
		//
		void unguard_getNewOrExistingPassword();
		void _getUserToEnterTheirExistingPassword(
			bool isForChangePassword,
			bool isForAuthorizingAppActionOnly,
			optional<string> customNavigationBarTitle,
			std::function<void(
				optional<bool> didCancel_orNone,
				optional<EnterPW_Fn_ValidationErr_Code> validationErr_orNone,
				optional<Password> obtainedPasswordString
			)> fn
		);
		void __cancelAnyAndRebuildUnlockTimer();
		//
		void obtainNewPasswordFromUser(bool isForChangePassword);
		//
		std::vector<ChangePasswordRegistrant *> ptrsTo_changePasswordRegistrants;
		optional<EnterPW_Fn_ValidationErr_Code> _changePassword_tellRegistrants_doChangePassword();
		//
		std::vector<DeleteEverythingRegistrant *> ptrsTo_deleteEverythingRegistrants;
		void _deconstructBootedStateAndClearPassword(
			bool isForADeleteEverything,
			std::function<void(std::function<void(optional<string> err_str)> cb)> optl__hasFiredWill_fn,
			std::function<void(optional<string> err_str)> optl__fn
		);
		//
		// Delegation - State
		void _didObtainPassword(Password password);
		//
		// Delegation - Events
		void UserIdle_userDidBecomeIdle();
		void _didBecomeIdleAfterHavingPreviouslyEnteredPassword();
	};
}

#endif /* PasswordController_hpp */

ext: hpp

max_stars_repo_name: Toklio-project/mytokl-libapp-cpp

max_issues_repo_name: Toklio-project/mytokl-libapp-cpp

max_forks_repo_name: Toklio-project/mytokl-libapp-cpp


text:
#include <asio_pq/detail/socket.hpp>

#include <boost/asio/ip/tcp.hpp>
#include <boost/asio/local/stream_protocol.hpp>
#include <boost/system/error_code.hpp>
#include <libpq-fe.h>
#include <cstring>

#ifdef _WIN32
#include <Winsock2.h>
#include <Windows.h>
#else
#include <errno.h>
#include <sys/socket.h>
#include <unistd.h>
#endif

namespace asio_pq {
namespace detail {

socket_type get_socket_type (PGconn * conn, boost::system::error_code & ec) noexcept {
	ec.clear();
	socket_type retr = socket_type::tcp_ip_v4;
	int handle = PQsocket(conn);
	if (handle == -1) {
		ec = make_error_code(boost::system::errc::not_a_socket);
		return retr;
	}
	struct sockaddr_storage addr;
	std::memset(&addr, 0, sizeof(addr));
	#ifdef _WIN32
	int
	#else
	socklen_t
	#endif
	size = sizeof(addr);
	if (getsockname(
		handle,
		reinterpret_cast<struct sockaddr *>(&addr),
		&size
	) == -1) {
		ec.assign(
			#ifdef _WIN32
			GetLastError()
			#else
			errno
			#endif
			, boost::system::system_category()
		);
		return retr;
	}
	switch (addr.ss_family) {
	case AF_INET:
		break;	//	Already correct
	case AF_INET6:
		retr = socket_type::tcp_ip_v6;
		break;
	#ifdef AF_UNIX
	case AF_UNIX:
	#endif
	#if defined(AF_LOCAL) && (!defined(AF_UNIX) || (AF_LOCAL != AF_UNIX))
	case AF_LOCAL:
	#endif
		#if defined(AF_LOCAL) || defined(AF_UNIX)
		retr = socket_type::unix_domain;
		break;
		#endif
	default:
		ec = make_error_code(boost::system::errc::not_supported);
		break;
	}
	return retr;
}

static void close_if (int handle, boost::system::error_code ec) noexcept {
	if (!ec) return;
	#ifdef _WIN32
	closesocket(handle);
	#else
	close(handle);
	#endif
}

boost::asio::ip::tcp::socket tcp_socket (
	boost::asio::io_service & ios,
	PGconn * conn,
	bool v4,
	boost::system::error_code & ec
) noexcept {
	ec.clear();
	boost::asio::ip::tcp::socket retr(ios);
	int handle = PQsocket(conn);
	#ifdef _WIN32
	WSAPROTOCOL_INFOW info;
	if (WSADuplicateSocketW(
		handle,
		GetProcessId(GetCurrentProcess()),
		&info
	) == SOCKET_ERROR) {
		ec.assign(GetLastError(), boost::system::system_category());
		return retr;
	}
	auto dup = WSASocketW(
		info.iAddressFamily,
		info.iSocketType,
		info.iProtocol,
		&info,
		0,
		WSA_FLAG_OVERLAPPED
	);
	if (dup == INVALID_SOCKET) {
		ec.assign(GetLastError(), boost::system::system_category());
		return retr;
	}
	#else
	auto dup = ::dup(handle);
	if (dup == -1) {
		ec.assign(errno, boost::system::system_category());
		return retr;
	}
	#endif
	retr.assign(
		v4 ? boost::asio::ip::tcp::v4() : boost::asio::ip::tcp::v6(),
		dup,
		ec
	);
	close_if(dup, ec);
	return retr;
}

#ifdef ASIO_PQ_HAS_LOCAL_SOCKETS
boost::asio::local::stream_protocol::socket local_socket (
	boost::asio::io_service & ios,
	PGconn * conn,
	boost::system::error_code & ec
) noexcept {
	ec.clear();
	boost::asio::local::stream_protocol::socket retr(ios);
	int handle = PQsocket(conn);
	auto dup = ::dup(handle);
	if (dup == -1) {
		ec.assign(errno, boost::system::system_category());
		return retr;
	}
	retr.assign(
		boost::asio::local::stream_protocol{},
		dup,
		ec
	);
	close_if(dup, ec);
	return retr;
}
#endif

socket_variant_type socket (boost::asio::io_service & ios, PGconn * conn, boost::system::error_code & ec) {
	ec.clear();
	if (!conn) {
		ec = make_error_code(boost::system::errc::invalid_argument);
		return boost::asio::ip::tcp::socket(ios);
	}
	socket_type type = get_socket_type(conn, ec);
	if (ec) {
		return boost::asio::ip::tcp::socket(ios);
	}
	bool v4 = false;
	switch (type) {
	case socket_type::tcp_ip_v4:
		v4 = true;
	case socket_type::tcp_ip_v6:{
		return detail::tcp_socket(ios, conn, v4, ec);
	}
	case socket_type::unix_domain:
		#ifdef ASIO_PQ_HAS_LOCAL_SOCKETS
		return detail::local_socket(ios, conn, ec);
		#else
		ec = make_error_code(boost::system::errc::not_supported);
		#endif
		break;
	}
	return boost::asio::ip::tcp::socket(ios);
}

}
}


text:
// ------------------------------------------------------------
// Copyright (c) Microsoft Corporation.  All rights reserved.
// Licensed under the MIT License (MIT). See License.txt in the repo root for license information.
// ------------------------------------------------------------

#include "stdafx.h"

#include <boost/test/unit_test.hpp>
#include "Common/boost-taef.h"

namespace ServiceModelTests
{
    using namespace std;
    using namespace Common;
    using namespace ServiceModel;

    StringLiteral const TestSource("ServiceModelParserTest");

    class ServiceModelParserTest
    {
    protected:
        static wstring GetTestFilePath(wstring const & testFileName);
        static void ParseConfigSettings(wstring const & testFileName);
        static void ParseAndValidateTargetInformationFile(wstring const & fileName, bool expectValidCurrentInstallation, bool expectValidTargetInstallation);
        void ApplicationHealthPolicyTestInternal(wstring const & testFileName, ApplicationHealthPolicy const & expectedPolicy);
        void ApplicationPoliciesTestInternal(wstring const & testFileName, ApplicationPoliciesDescription const & appPoliciesDescription);
    };

    BOOST_FIXTURE_TEST_SUITE(ServiceModelParserTestSuite,ServiceModelParserTest)

    BOOST_AUTO_TEST_CASE(ApplicationHealthPolicyTest)
    {
        {
            // Test 1: ApplicationHealthPolicy is not specified, parse default
            ApplicationHealthPolicy expectedPolicy;
            this->ApplicationHealthPolicyTestInternal(
                GetTestFilePath(L"ApplicationPackage-HealthPolicy-1.1.0.xml"),
                expectedPolicy);
        }

        {
            // Test 2: Empty health policy element, should parse default
            ApplicationHealthPolicy expectedPolicy;
            this->ApplicationHealthPolicyTestInternal(
                GetTestFilePath(L"ApplicationPackage-HealthPolicy-2.1.0.xml"),
                expectedPolicy);
        }

        {
            // Test 3: ApplicationHealthPolicy specified, no ServiceTypeHealthPolicies
            ApplicationHealthPolicy expectedPolicy;
            expectedPolicy.ConsiderWarningAsError = true;
            expectedPolicy.MaxPercentUnhealthyDeployedApplications = 20;
            this->ApplicationHealthPolicyTestInternal(
                GetTestFilePath(L"ApplicationPackage-HealthPolicy-3.1.0.xml"),
                expectedPolicy);
        }

        {
            // Test 4: ApplicationHealthPolicy specified, non empty element
            ApplicationHealthPolicy expectedPolicy;
            expectedPolicy.ConsiderWarningAsError = true;
            expectedPolicy.MaxPercentUnhealthyDeployedApplications = 20;
            this->ApplicationHealthPolicyTestInternal(
                GetTestFilePath(L"ApplicationPackage-HealthPolicy-4.1.0.xml"),
                expectedPolicy);
        }

        {
            // Test 5: Default DefaultServiceTypeHealthPolicy, default ServiceTypeHealthPolicy
            ApplicationHealthPolicy expectedPolicy;
            expectedPolicy.ConsiderWarningAsError = true;
            expectedPolicy.MaxPercentUnhealthyDeployedApplications = 20;
            expectedPolicy.ServiceTypeHealthPolicies.insert(
                make_pair(L"HealthPolicyServiceTypeName", ServiceTypeHealthPolicy()));

            this->ApplicationHealthPolicyTestInternal(
                GetTestFilePath(L"ApplicationPackage-HealthPolicy-5.1.0.xml"),
                expectedPolicy);
        }

        {
            // Test 6: all policies specified
            ApplicationHealthPolicy expectedPolicy;
            expectedPolicy.ConsiderWarningAsError = true;
            expectedPolicy.MaxPercentUnhealthyDeployedApplications = 20;

            expectedPolicy.DefaultServiceTypeHealthPolicy.MaxPercentUnhealthyServices = 30;
            expectedPolicy.DefaultServiceTypeHealthPolicy.MaxPercentUnhealthyPartitionsPerService = 100;
            expectedPolicy.DefaultServiceTypeHealthPolicy.MaxPercentUnhealthyReplicasPerPartition = 0;

            expectedPolicy.ServiceTypeHealthPolicies.insert(
                make_pair(L"HealthPolicyServiceTypeName1", ServiceTypeHealthPolicy(30, 40, 50)));
            expectedPolicy.ServiceTypeHealthPolicies.insert(
                make_pair(L"HealthPolicyServiceTypeName2", ServiceTypeHealthPolicy(0, 10, 20)));

            this->ApplicationHealthPolicyTestInternal(
                GetTestFilePath(L"ApplicationPackage-HealthPolicy-6.1.0.xml"),
                expectedPolicy);
        }
    }

    BOOST_AUTO_TEST_CASE(ApplicationPoliciesTest)
    {
        {
            // Test 1: Only log collection policies specified
            ApplicationPoliciesDescription expectedPolicy;
            expectedPolicy.LogCollectionEntries.push_back(LogCollectionPolicyDescription());
            LogCollectionPolicyDescription policyDes1, policyDes2;
            policyDes1.Path = L"innerFolder1";
            expectedPolicy.LogCollectionEntries.push_back(policyDes1);
            policyDes2.Path = L"innerFolder2";
            expectedPolicy.LogCollectionEntries.push_back(policyDes2);
            expectedPolicy.DefaultRunAs.UserRef = L"MyUser";
            this->ApplicationPoliciesTestInternal(
                GetTestFilePath(L"ApplicationPackage-Policies-1.1.0.xml"),
                expectedPolicy);
        }

        {
            // Test 2: LogCollectionPolicies, DefaultRunAs and Health
            ApplicationPoliciesDescription expectedPolicy;
            expectedPolicy.LogCollectionEntries.push_back(LogCollectionPolicyDescription());
            LogCollectionPolicyDescription policyDes1, policyDes2;
            policyDes1.Path = L"innerFolder1";
            expectedPolicy.LogCollectionEntries.push_back(policyDes1);
            policyDes2.Path = L"innerFolder2";
            expectedPolicy.LogCollectionEntries.push_back(policyDes2);
            expectedPolicy.DefaultRunAs.UserRef = L"MyUser";
            expectedPolicy.HealthPolicy.ConsiderWarningAsError = true;
            expectedPolicy.HealthPolicy.MaxPercentUnhealthyDeployedApplications = 20;
            this->ApplicationPoliciesTestInternal(
                GetTestFilePath(L"ApplicationPackage-Policies-2.1.0.xml"),
                expectedPolicy);
        }

        {
            // Test 3: Health and DefaultRunAs
            ApplicationPoliciesDescription expectedPolicy;
            expectedPolicy.DefaultRunAs.UserRef = L"MyUser";
            expectedPolicy.HealthPolicy.ConsiderWarningAsError = true;
            expectedPolicy.HealthPolicy.MaxPercentUnhealthyDeployedApplications = 20;
            this->ApplicationPoliciesTestInternal(
                GetTestFilePath(L"ApplicationPackage-Policies-3.1.0.xml"),
                expectedPolicy);
        }
    }

    BOOST_AUTO_TEST_CASE(ServicePackageTest)
    {
        ServicePackageDescription servicePackage;

        auto error = Parser::ParseServicePackage(
            GetTestFilePath(L"CalculatorSample.Package.Bootstrap.xml"),
            servicePackage);

        Trace.WriteNoise(TestSource, "ParseServicePackage={0}", error);
        VERIFY_IS_TRUE(error.IsSuccess(), L"ParseServicePackage.IsSuccess");
    }

    BOOST_AUTO_TEST_CASE(ServicePackageWithDiagnosticsTest)
    {
        ServicePackageDescription servicePackage;

        auto error = Parser::ParseServicePackage(
            GetTestFilePath(L"CalculatorSample.Package.WithDiagnostics.xml"),
            servicePackage);

        Trace.WriteNoise(TestSource, "ParseServicePackage={0}", error);
        VERIFY_IS_TRUE(error.IsSuccess(), L"ParseServicePackage.IsSuccess");
    }

    BOOST_AUTO_TEST_CASE(ServiceManifestTest)
    {
        ServiceManifestDescription serviceManifest;

        auto error = Parser::ParseServiceManifest(
            GetTestFilePath(L"CalculatorSample.Manifest.1.0.xml"),
            serviceManifest);

        Trace.WriteNoise(TestSource, "ParseServiceManifest={0}", error);
        VERIFY_IS_TRUE(error.IsSuccess(), L"ParseServiceManifest.IsSuccess");

        wstring fileName(L"CalculatorSample.Manifest.Endpoints");
        EndpointDescription::WriteToFile(fileName, serviceManifest.Resources.Endpoints);

        vector<EndpointDescription> endpointDescriptions;
        EndpointDescription::ReadFromFile(fileName, endpointDescriptions);
        VERIFY_IS_TRUE(endpointDescriptions.size() == serviceManifest.Resources.Endpoints.size());
        for(size_t i = 0; i < endpointDescriptions.size(); ++i)
        {
            VERIFY_IS_TRUE(endpointDescriptions[i] == serviceManifest.Resources.Endpoints[i]);
        }
    }

    BOOST_AUTO_TEST_CASE(ServiceManifestWithServiceGroupTest)
    {
        ServiceManifestDescription serviceManifest;

        auto error = Parser::ParseServiceManifest(
            GetTestFilePath(L"ServiceGroupSample.Manifest.1.0.xml"),
            serviceManifest);

        Trace.WriteNoise(TestSource, "ParseServiceManifest={0}", error);
        VERIFY_IS_TRUE(error.IsSuccess(), L"ParseServiceManifest.IsSuccess");
    }

    BOOST_AUTO_TEST_CASE(ServiceManifestWithRunFrequencyAndConsoleRedirection)
    {
        ServiceManifestDescription serviceManifest;

        auto error = Parser::ParseServiceManifest(
            GetTestFilePath(L"CalculatorSample.Manifest.2.0.xml"),
            serviceManifest);

        Trace.WriteNoise(TestSource, "ParseServiceManifest={0}", error);
        VERIFY_IS_TRUE(error.IsSuccess(), L"ParseServiceManifest.IsSuccess");
    }

    BOOST_AUTO_TEST_CASE(ServiceManifestNegtiveTest)
    {
        ServiceManifestDescription serviceManifest;

        auto error = Parser::ParseServiceManifest(
            GetTestFilePath(L"CalculatorSample.Manifest.3.0.xml"),
            serviceManifest);

        Trace.WriteNoise(TestSource, "ParseServiceManifest={0}", error);
        VERIFY_IS_FALSE(error.IsSuccess(), L"ParseServiceManifest.IsError");

        wstring fileName(L"CalculatorSample.Manifest.Endpoints");
        EndpointDescription::WriteToFile(fileName, serviceManifest.Resources.Endpoints);

        vector<EndpointDescription> endpointDescriptions;
        EndpointDescription::ReadFromFile(fileName, endpointDescriptions);
        VERIFY_IS_TRUE(endpointDescriptions.size() == serviceManifest.Resources.Endpoints.size());
        for (size_t i = 0; i < endpointDescriptions.size(); ++i)
        {
            VERIFY_IS_TRUE(endpointDescriptions[i] == serviceManifest.Resources.Endpoints[i]);
        }
    }

    BOOST_AUTO_TEST_CASE(ApplicationManifestTest)
    {
        ApplicationManifestDescription applicationManifest;

        auto error = Parser::ParseApplicationManifest(
            GetTestFilePath(L"ApplicationManifest.1.0.xml"),
            applicationManifest);

        Trace.WriteNoise(TestSource, "ParseApplicationManifest={0}", error);
        VERIFY_IS_TRUE(error.IsSuccess(), L"ParseApplicationManifest.IsSuccess");

        Trace.WriteNoise(TestSource, "{0}", applicationManifest);
        VERIFY_IS_TRUE(applicationManifest.Name == L"CalculatorApp");
        VERIFY_IS_TRUE(applicationManifest.Version == L"1.0");

        VERIFY_IS_TRUE(applicationManifest.ServiceManifestImports.size() == 2);

		VERIFY_IS_TRUE(applicationManifest.ServiceManifestImports[0].ServiceManifestRef.Name == L"CalculatorServicePackage");
		VERIFY_IS_TRUE(applicationManifest.ServiceManifestImports[1].ServiceManifestRef.Name == L"CalculatorGatewayPackage");

		VERIFY_IS_TRUE(applicationManifest.ServiceManifestImports[0].ServiceManifestRef.Version == L"2.0");
		VERIFY_IS_TRUE(applicationManifest.ServiceManifestImports[1].ServiceManifestRef.Version == L"3.0");

        VERIFY_IS_TRUE(applicationManifest.ApplicationParameters.size() == 1);
        VERIFY_IS_TRUE(applicationManifest.ApplicationParameters.count(L"ServiceInstanceCount") == 1);
        VERIFY_IS_TRUE(applicationManifest.ApplicationParameters[L"ServiceInstanceCount"] == L"3");

        VERIFY_IS_TRUE(applicationManifest.DefaultServices.size() == 3, L"Default service count.");

        VERIFY_IS_TRUE(applicationManifest.DefaultServices[0].Name == L"RequiredCalcService", L"Default service Name.");
        VERIFY_IS_TRUE(applicationManifest.DefaultServices[0].PackageActivationMode == L"SharedProcess", L"Default service PackageActivationMode");
		VERIFY_IS_TRUE(applicationManifest.DefaultServices[0].ServiceDnsName == L"", L"Default service ServiceDnsName");

        VERIFY_IS_TRUE(applicationManifest.DefaultServices[1].Name == L"RequiredCalcServiceShared", L"Default service Name.");
        VERIFY_IS_TRUE(applicationManifest.DefaultServices[1].PackageActivationMode == L"SharedProcess", L"Default service PackageActivationMode");
		VERIFY_IS_TRUE(applicationManifest.DefaultServices[1].ServiceDnsName == L"", L"Default service ServiceDnsName");

        VERIFY_IS_TRUE(applicationManifest.DefaultServices[2].Name == L"RequiredCalcServiceExclusive", L"Default service Name.");
        VERIFY_IS_TRUE(applicationManifest.DefaultServices[2].PackageActivationMode == L"ExclusiveProcess", L"Default service PackageActivationMode");
		VERIFY_IS_TRUE(applicationManifest.DefaultServices[2].ServiceDnsName == L"Required.CalcService.Exclusive", L"Default service ServiceDnsName");

        error = Parser::ParseApplicationManifest(
            GetTestFilePath(L"ApplicationManifest.2.0.xml"),
            applicationManifest);

        Trace.WriteNoise(TestSource, "ParseApplicationManifestWithEmptyPolicies={0}", error);
        VERIFY_IS_TRUE(error.IsSuccess(), L"ParseApplicationManifestWithEmptyPolicies.IsSuccess");

        VERIFY_IS_TRUE(applicationManifest.DefaultServices.size() == 4, L"default service count");

        VERIFY_IS_FALSE(applicationManifest.DefaultServices[0].DefaultService.IsServiceGroup, L"non-servicegroup service");
        VERIFY_IS_TRUE(applicationManifest.DefaultServices[1].DefaultService.IsServiceGroup, L"servicegroup service");
        VERIFY_IS_TRUE(applicationManifest.DefaultServices[2].DefaultService.IsServiceGroup, L"servicegroup service");
        VERIFY_IS_TRUE(applicationManifest.DefaultServices[3].DefaultService.IsServiceGroup, L"servicegroup service");

        VERIFY_IS_TRUE(applicationManifest.DefaultServices[0].Name == L"Service1", L"service name");
        VERIFY_IS_TRUE(applicationManifest.DefaultServices[0].PackageActivationMode == L"SharedProcess", L"service PackageActivationMode");

        VERIFY_IS_TRUE(applicationManifest.DefaultServices[1].Name == L"ServiceGroup1", L"servicegroup name");
        VERIFY_IS_TRUE(applicationManifest.DefaultServices[1].PackageActivationMode == L"SharedProcess", L"service group PackageActivationMode");

        VERIFY_IS_TRUE(applicationManifest.DefaultServices[2].Name == L"ServiceGroup2", L"servicegroup name");
        VERIFY_IS_TRUE(applicationManifest.DefaultServices[2].PackageActivationMode == L"SharedProcess", L"service group PackageActivationMode");

        VERIFY_IS_TRUE(applicationManifest.DefaultServices[3].Name == L"ServiceGroup3", L"servicegroup name");
        VERIFY_IS_TRUE(applicationManifest.DefaultServices[3].PackageActivationMode == L"ExclusiveProcess", L"service group PackageActivationMode");

        VERIFY_IS_TRUE(applicationManifest.DefaultServices[1].DefaultService.IsStateful, L"stateful servicegroup");
        VERIFY_IS_FALSE(applicationManifest.DefaultServices[2].DefaultService.IsStateful, L"stateless servicegroup");
        VERIFY_IS_FALSE(applicationManifest.DefaultServices[3].DefaultService.IsStateful, L"stateless servicegroup");

        VERIFY_IS_TRUE(applicationManifest.DefaultServices[1].DefaultService.ServiceGroupMembers.size() == 2, L"service group member count");
        VERIFY_IS_TRUE(applicationManifest.DefaultServices[2].DefaultService.ServiceGroupMembers.size() == 2, L"service group member count");
        VERIFY_IS_TRUE(applicationManifest.DefaultServices[3].DefaultService.ServiceGroupMembers.size() == 2, L"service group member count");

        VERIFY_IS_TRUE(applicationManifest.DefaultServices[1].DefaultService.ServiceGroupMembers[0].LoadMetrics.size() == 0, L"no load metrics");
        VERIFY_IS_TRUE(applicationManifest.DefaultServices[1].DefaultService.ServiceGroupMembers[1].LoadMetrics.size() == 0, L"no load metrics");
        VERIFY_IS_TRUE(applicationManifest.DefaultServices[2].DefaultService.ServiceGroupMembers[0].LoadMetrics.size() == 0, L"no load metrics");
        VERIFY_IS_TRUE(applicationManifest.DefaultServices[2].DefaultService.ServiceGroupMembers[1].LoadMetrics.size() == 1, L"load metrics");
        VERIFY_IS_TRUE(applicationManifest.DefaultServices[3].DefaultService.ServiceGroupMembers[0].LoadMetrics.size() == 0, L"no load metrics");
        VERIFY_IS_TRUE(applicationManifest.DefaultServices[3].DefaultService.ServiceGroupMembers[1].LoadMetrics.size() == 1, L"load metrics");
    }

    BOOST_AUTO_TEST_CASE(ApplicationManifestTestWithContainerHostPolicies)
    {
        ApplicationManifestDescription applicationManifest;

        auto error = Parser::ParseApplicationManifest(
            GetTestFilePath(L"ApplicationManifest.3.0.xml"),
            applicationManifest);

        Trace.WriteNoise(TestSource, "ParseApplicationManifest={0}", error);
        VERIFY_IS_TRUE(error.IsSuccess(), L"ParseApplicationManifest.IsSuccess");

        Trace.WriteNoise(TestSource, "{0}", applicationManifest);
        VERIFY_IS_TRUE(applicationManifest.Name == L"ContainerApplicationType");
        VERIFY_IS_TRUE(applicationManifest.Version == L"2.0.0");

        VERIFY_IS_TRUE(applicationManifest.ServiceManifestImports.size() == 1);

        VERIFY_IS_TRUE(applicationManifest.ServiceManifestImports[0].ServiceManifestRef.Name == L"ContainerServicePkg");

        VERIFY_IS_TRUE(applicationManifest.ServiceManifestImports[0].ServiceManifestRef.Version == L"2.0.0");

        VERIFY_IS_TRUE(applicationManifest.ServiceManifestImports[0].ContainerHostPolicies.size() == 1);

        VERIFY_IS_TRUE(applicationManifest.ServiceManifestImports[0].ContainerHostPolicies[0].CodePackageRef == L"Code");
        VERIFY_IS_TRUE(applicationManifest.ServiceManifestImports[0].ContainerHostPolicies[0].RepositoryCredentials.AccountName == L"sftestcontainerreg");
        VERIFY_IS_TRUE(applicationManifest.ServiceManifestImports[0].ContainerHostPolicies[0].RepositoryCredentials.Password == L"[ContainerRepositoryPassword]");

        VERIFY_IS_TRUE(applicationManifest.ServiceManifestImports[0].ContainerHostPolicies[0].HealthConfig.IncludeDockerHealthStatusInSystemHealthReport == false);
        VERIFY_IS_TRUE(applicationManifest.ServiceManifestImports[0].ContainerHostPolicies[0].HealthConfig.RestartContainerOnUnhealthyDockerHealthStatus == true);

        VERIFY_IS_TRUE(applicationManifest.ApplicationParameters.size() == 1);
        VERIFY_IS_TRUE(applicationManifest.ApplicationParameters.count(L"ContainerRepositoryPassword") == 1);
        VERIFY_IS_TRUE(applicationManifest.ApplicationParameters[L"ContainerRepositoryPassword"] == L"");

        VERIFY_IS_TRUE(applicationManifest.ServiceManifestImports[0].ContainerHostPolicies[0].PortBindings.size() == 1);
        VERIFY_IS_TRUE(applicationManifest.ServiceManifestImports[0].ContainerHostPolicies[0].PortBindings[0].ContainerPort == 15243);
        VERIFY_IS_TRUE(applicationManifest.ServiceManifestImports[0].ContainerHostPolicies[0].PortBindings[0].EndpointResourceRef == L"Endpoint");

        VERIFY_IS_TRUE(applicationManifest.ServiceManifestImports[0].ContainerHostPolicies[0].CertificateRef.size() == 3);
        VERIFY_IS_TRUE(applicationManifest.ServiceManifestImports[0].ContainerHostPolicies[0].CertificateRef[0].X509StoreName == L"My");
        VERIFY_IS_TRUE(applicationManifest.ServiceManifestImports[0].ContainerHostPolicies[0].CertificateRef[0].X509FindValue == L"ad fc 91 97 13 16 8d 9f a8 ee 71 2b a2 f4 37 62 00 03 49 0d");
        VERIFY_IS_TRUE(applicationManifest.ServiceManifestImports[0].ContainerHostPolicies[0].CertificateRef[0].Name == L"MyCert1");

        VERIFY_IS_TRUE(applicationManifest.ServiceManifestImports[0].ContainerHostPolicies[0].CertificateRef[1].DataPackageRef == L"Data");
        VERIFY_IS_TRUE(applicationManifest.ServiceManifestImports[0].ContainerHostPolicies[0].CertificateRef[1].DataPackageVersion == L"1.0");
        VERIFY_IS_TRUE(applicationManifest.ServiceManifestImports[0].ContainerHostPolicies[0].CertificateRef[1].RelativePath == L"Certificate.pfx");
        VERIFY_IS_TRUE(applicationManifest.ServiceManifestImports[0].ContainerHostPolicies[0].CertificateRef[1].Password == L"password");
        VERIFY_IS_FALSE(applicationManifest.ServiceManifestImports[0].ContainerHostPolicies[0].CertificateRef[1].IsPasswordEncrypted);
        VERIFY_IS_TRUE(applicationManifest.ServiceManifestImports[0].ContainerHostPolicies[0].CertificateRef[1].Name == L"MyCert2");

        VERIFY_IS_TRUE(applicationManifest.ServiceManifestImports[0].ContainerHostPolicies[0].CertificateRef[2].DataPackageRef == L"Data");
        VERIFY_IS_TRUE(applicationManifest.ServiceManifestImports[0].ContainerHostPolicies[0].CertificateRef[2].DataPackageVersion == L"2.0");
        VERIFY_IS_TRUE(applicationManifest.ServiceManifestImports[0].ContainerHostPolicies[0].CertificateRef[2].RelativePath == L"Certificate.pfx");
        VERIFY_IS_TRUE(applicationManifest.ServiceManifestImports[0].ContainerHostPolicies[0].CertificateRef[2].Password == L"password");
        VERIFY_IS_TRUE(applicationManifest.ServiceManifestImports[0].ContainerHostPolicies[0].CertificateRef[2].IsPasswordEncrypted);
        VERIFY_IS_TRUE(applicationManifest.ServiceManifestImports[0].ContainerHostPolicies[0].CertificateRef[2].Name == L"MyCert3");

        VERIFY_IS_TRUE(applicationManifest.ServiceManifestImports[0].ContainerHostPolicies[0].LogConfig.Driver == L"etwlogs");
        VERIFY_IS_TRUE(applicationManifest.ServiceManifestImports[0].ContainerHostPolicies[0].LogConfig.DriverOpts.size() == 1);
        VERIFY_IS_TRUE(applicationManifest.ServiceManifestImports[0].ContainerHostPolicies[0].LogConfig.DriverOpts[0].Name == L"test");
        VERIFY_IS_TRUE(applicationManifest.ServiceManifestImports[0].ContainerHostPolicies[0].LogConfig.DriverOpts[0].Value == L"value");

        VERIFY_IS_TRUE(applicationManifest.ServiceManifestImports[0].ContainerHostPolicies[0].Volumes.size() == 3);
        VERIFY_IS_TRUE(applicationManifest.ServiceManifestImports[0].ContainerHostPolicies[0].Volumes[0].Source == L"c:\\workspace");
        VERIFY_IS_TRUE(applicationManifest.ServiceManifestImports[0].ContainerHostPolicies[0].Volumes[0].Destination == L"c:\\testmountlocation1");
        VERIFY_IS_FALSE(applicationManifest.ServiceManifestImports[0].ContainerHostPolicies[0].Volumes[0].IsReadOnly);
        VERIFY_IS_TRUE(applicationManifest.ServiceManifestImports[0].ContainerHostPolicies[0].Volumes[1].Source == L"d:\\myfolder");
        VERIFY_IS_TRUE(applicationManifest.ServiceManifestImports[0].ContainerHostPolicies[0].Volumes[1].Destination == L"c:\\testmountlocation2");
        VERIFY_IS_TRUE(applicationManifest.ServiceManifestImports[0].ContainerHostPolicies[0].Volumes[1].IsReadOnly);
        VERIFY_IS_TRUE(applicationManifest.ServiceManifestImports[0].ContainerHostPolicies[0].Volumes[2].Source == L"myexternalvolume");
        VERIFY_IS_TRUE(applicationManifest.ServiceManifestImports[0].ContainerHostPolicies[0].Volumes[2].Destination == L"c:\\testmountlocation3");
        VERIFY_IS_TRUE(applicationManifest.ServiceManifestImports[0].ContainerHostPolicies[0].Volumes[2].IsReadOnly);
        VERIFY_IS_TRUE(applicationManifest.ServiceManifestImports[0].ContainerHostPolicies[0].Volumes[2].Driver == L"sf");
    }

    BOOST_AUTO_TEST_CASE(ApplicationManifestWithEmptyPolicyTest)
    {
        ApplicationManifestDescription applicationManifest;
        auto error = Parser::ParseApplicationManifest(
            GetTestFilePath(L"ApplicationManifest.2.0.xml"),
            applicationManifest);

        Trace.WriteNoise(TestSource, "ParseApplicationManifestWithEmptyPolicies={0}", error);
        VERIFY_IS_TRUE(error.IsSuccess(), L"ParseApplicationManifestWithEmptyPolicies.IsSuccess");
    }

    BOOST_AUTO_TEST_CASE(ApplicationInstanceTest)
    {
        ApplicationInstanceDescription applicationInstance;

        auto error = Parser::ParseApplicationInstance(
            GetTestFilePath(L"ApplicationInstance.1.xml"),
            applicationInstance);

        Trace.WriteNoise(TestSource, "ParseApplicationInstance={0}", error);
        VERIFY_IS_TRUE(error.IsSuccess(), L"ParseApplicationInstance.IsSuccess");

        VERIFY_IS_TRUE(applicationInstance.DefaultServices.size() == 3, L"Default service count");

        VERIFY_IS_TRUE(applicationInstance.DefaultServices[0].Name == L"Service1", L"Default service Name.");
        VERIFY_IS_TRUE(applicationInstance.DefaultServices[0].PackageActivationMode == ServicePackageActivationMode::SharedProcess, L"Default service PackageActivationMode");
		VERIFY_IS_TRUE(applicationInstance.DefaultServices[0].ServiceDnsName == L"", L"Default service ServiceDnsName");

        VERIFY_IS_TRUE(applicationInstance.DefaultServices[1].Name == L"Service2", L"Default service Name.");
        VERIFY_IS_TRUE(applicationInstance.DefaultServices[1].PackageActivationMode == ServicePackageActivationMode::SharedProcess, L"Default service PackageActivationMode");
		VERIFY_IS_TRUE(applicationInstance.DefaultServices[1].ServiceDnsName == L"", L"Default service ServiceDnsName");

        VERIFY_IS_TRUE(applicationInstance.DefaultServices[2].Name == L"Service3", L"Default service Name.");
        VERIFY_IS_TRUE(applicationInstance.DefaultServices[2].PackageActivationMode == ServicePackageActivationMode::ExclusiveProcess, L"Default service PackageActivationMode");
		VERIFY_IS_TRUE(applicationInstance.DefaultServices[2].ServiceDnsName == L"Service3.Dns.Name", L"Default service ServiceDnsName");
    }

    BOOST_AUTO_TEST_CASE(ApplicationInstanceWithDefaultServiceGroupTest)
    {
        ApplicationInstanceDescription applicationInstance;

        auto error = Parser::ParseApplicationInstance(
            GetTestFilePath(L"ApplicationInstanceWithDefaultServiceGroup.1.xml"),
            applicationInstance);

        Trace.WriteNoise(TestSource, "ParseApplicationInstance={0}", error);
        VERIFY_IS_TRUE(error.IsSuccess(), L"ParseApplicationInstance.IsSuccess");

        VERIFY_IS_TRUE(applicationInstance.DefaultServices.size() == 4, L"default service count");

        VERIFY_IS_FALSE(applicationInstance.DefaultServices[0].DefaultService.IsServiceGroup, L"non-servicegroup service");
        VERIFY_IS_TRUE(applicationInstance.DefaultServices[1].DefaultService.IsServiceGroup, L"servicegroup service");
        VERIFY_IS_TRUE(applicationInstance.DefaultServices[2].DefaultService.IsServiceGroup, L"servicegroup service");
        VERIFY_IS_TRUE(applicationInstance.DefaultServices[3].DefaultService.IsServiceGroup, L"servicegroup service");

        VERIFY_IS_TRUE(applicationInstance.DefaultServices[0].Name == L"Service1", L"service name");
        VERIFY_IS_TRUE(applicationInstance.DefaultServices[0].PackageActivationMode == ServicePackageActivationMode::SharedProcess, L"service PackageActivationMode");

        VERIFY_IS_TRUE(applicationInstance.DefaultServices[1].Name == L"ServiceGroup1", L"servicegroup name");
        VERIFY_IS_TRUE(applicationInstance.DefaultServices[1].PackageActivationMode == ServicePackageActivationMode::SharedProcess, L"service group PackageActivationMode");

        VERIFY_IS_TRUE(applicationInstance.DefaultServices[2].Name == L"ServiceGroup2", L"servicegroup name");
        VERIFY_IS_TRUE(applicationInstance.DefaultServices[2].PackageActivationMode == ServicePackageActivationMode::SharedProcess, L"service group PackageActivationMode");

        VERIFY_IS_TRUE(applicationInstance.DefaultServices[3].Name == L"ServiceGroup3", L"servicegroup name");
        VERIFY_IS_TRUE(applicationInstance.DefaultServices[3].PackageActivationMode == ServicePackageActivationMode::ExclusiveProcess, L"service group PackageActivationMode");

        VERIFY_IS_TRUE(applicationInstance.DefaultServices[1].DefaultService.IsStateful, L"stateful servicegroup");
        VERIFY_IS_FALSE(applicationInstance.DefaultServices[2].DefaultService.IsStateful, L"stateless servicegroup");
        VERIFY_IS_FALSE(applicationInstance.DefaultServices[3].DefaultService.IsStateful, L"stateless servicegroup");

        VERIFY_IS_TRUE(applicationInstance.DefaultServices[1].DefaultService.ServiceGroupMembers.size() == 2, L"service group member count");
        VERIFY_IS_TRUE(applicationInstance.DefaultServices[2].DefaultService.ServiceGroupMembers.size() == 2, L"service group member count");
        VERIFY_IS_TRUE(applicationInstance.DefaultServices[3].DefaultService.ServiceGroupMembers.size() == 2, L"service group member count");

        VERIFY_IS_TRUE(applicationInstance.DefaultServices[1].DefaultService.ServiceGroupMembers[0].LoadMetrics.size() == 0, L"no load metrics");
        VERIFY_IS_TRUE(applicationInstance.DefaultServices[1].DefaultService.ServiceGroupMembers[1].LoadMetrics.size() == 0, L"no load metrics");
        VERIFY_IS_TRUE(applicationInstance.DefaultServices[2].DefaultService.ServiceGroupMembers[0].LoadMetrics.size() == 0, L"no load metrics");
        VERIFY_IS_TRUE(applicationInstance.DefaultServices[2].DefaultService.ServiceGroupMembers[1].LoadMetrics.size() == 1, L"load metrics");
        VERIFY_IS_TRUE(applicationInstance.DefaultServices[3].DefaultService.ServiceGroupMembers[0].LoadMetrics.size() == 0, L"no load metrics");
        VERIFY_IS_TRUE(applicationInstance.DefaultServices[3].DefaultService.ServiceGroupMembers[1].LoadMetrics.size() == 1, L"load metrics");
    }

    BOOST_AUTO_TEST_CASE(ApplicationPackageTest)
    {
        ApplicationPackageDescription applicationPackage;

        auto error = Parser::ParseApplicationPackage(
            GetTestFilePath(L"ApplicationPackage.1.0.xml"),
            applicationPackage);

        Trace.WriteNoise(TestSource, "ParseApplicationPackage={0}", error);
        VERIFY_IS_TRUE(error.IsSuccess(), L"ParseApplicationPackage.IsSuccess");
    }

    BOOST_AUTO_TEST_CASE(ApplicationPackageWithDiagnosticsTest)
    {
        ApplicationPackageDescription applicationPackage;

        auto error = Parser::ParseApplicationPackage(
            GetTestFilePath(L"ApplicationPackageWithDiagnostics.1.xml"),
            applicationPackage);

        Trace.WriteNoise(TestSource, "ParseApplicationPackage={0}", error);
        VERIFY_IS_TRUE(error.IsSuccess(), L"ParseApplicationPackage.IsSuccess");
    }

    BOOST_AUTO_TEST_CASE(ConfigSettingsBasicTest)
    {
        ParseConfigSettings(GetTestFilePath(L"ConfigSettings-BasicTest-1.xml"));
        ParseConfigSettings(GetTestFilePath(L"ConfigSettings-BasicTest-2.xml"));
        ParseConfigSettings(GetTestFilePath(L"ConfigSettings-BasicTest-3.xml"));
        ParseConfigSettings(GetTestFilePath(L"ConfigSettings-BasicTest-4.xml"));
    }

    BOOST_AUTO_TEST_CASE(TargetInformationFileTest)
    {
        ParseAndValidateTargetInformationFile(GetTestFilePath(L"TargetInformation.Valid.xml"), true, true);
        ParseAndValidateTargetInformationFile(GetTestFilePath(L"TargetInformation.NoCurrentInstallation.xml"), false, true);
        ParseAndValidateTargetInformationFile(GetTestFilePath(L"TargetInformation.NoTargetInstallation.xml"), true, false);
        ParseAndValidateTargetInformationFile(GetTestFilePath(L"TargetInformation.Empty.xml"), false, false);
    }

    BOOST_AUTO_TEST_SUITE_END()

    void ServiceModelParserTest::ApplicationHealthPolicyTestInternal(wstring const & testFileName, ApplicationHealthPolicy const & expectedPolicy)
    {
        Trace.WriteNoise(TestSource, "ApplicationHealthPolicyTest(TestFileName={0}, ExpectedHPolicy={1}", testFileName, expectedPolicy);

        ApplicationPackageDescription appPackage;
        auto error = Parser::ParseApplicationPackage(testFileName, appPackage);
        Trace.WriteNoise(TestSource, "ParseApplicationPackage={0}", error);
        VERIFY_IS_TRUE(error.IsSuccess(), L"ParseApplicationPackage.IsSuccess");

        Trace.WriteNoise(TestSource, "ParsedPolicy={0}", appPackage.DigestedEnvironment.Policies.HealthPolicy);
        Trace.WriteNoise(TestSource, "ExpectedPolicy={0}", expectedPolicy);
        VERIFY_IS_TRUE(expectedPolicy == appPackage.DigestedEnvironment.Policies.HealthPolicy, L"Parsed Policy == Expected Policy");
    }

    void ServiceModelParserTest::ApplicationPoliciesTestInternal(wstring const & testFileName, ApplicationPoliciesDescription const & expectedPolicy)
    {
        Trace.WriteNoise(TestSource, "ApplicationPoliciesTest(TestFileName={0}, ExpectedPoliciesDescription={1}", testFileName, expectedPolicy);

        ApplicationPackageDescription appPackage;
        auto error = Parser::ParseApplicationPackage(testFileName, appPackage);
        Trace.WriteNoise(TestSource, "ParseApplicationPackage={0}", error);
        VERIFY_IS_TRUE(error.IsSuccess(), L"ParseApplicationPackage.IsSuccess");

        Trace.WriteNoise(TestSource, "ParsedPolicy={0}", appPackage.DigestedEnvironment.Policies);
        Trace.WriteNoise(TestSource, "ExpectedPolicy={0}", expectedPolicy);
        VERIFY_IS_TRUE(expectedPolicy == appPackage.DigestedEnvironment.Policies, L"Parsed Policy == Expected Policy");
    }

    wstring ServiceModelParserTest::GetTestFilePath(wstring const & testFileName)
    {
        wstring folder = Directory::GetCurrentDirectoryW();
        wstring filePath = Path::Combine(folder, testFileName);

        if (!File::Exists(filePath))
        {
            wstring unitTestsFolder;
#if !defined(PLATFORM_UNIX)
            VERIFY_IS_TRUE(
                Environment::ExpandEnvironmentStringsW(L"%_NTTREE%\\FabricUnitTests", unitTestsFolder),
                L"ExpandEnvironmentStringsW");
#else
            VERIFY_IS_TRUE(
                Environment::ExpandEnvironmentStringsW(L"%_NTTREE%/FabricUnitTests", unitTestsFolder),
                L"ExpandEnvironmentStringsW");
#endif

            return Path::Combine(unitTestsFolder, testFileName);
        }
        else
        {
            return filePath;
        }
    }

    void ServiceModelParserTest::ParseConfigSettings(wstring const & testFileName)
    {
        Trace.WriteInfo(TestSource, "Parsing Config Settings from {0}", testFileName);

        // parse the config settings
        ConfigSettings parsedConfigSettings;
        auto error = Parser::ParseConfigSettings(testFileName, parsedConfigSettings);
        VERIFY_IS_TRUE(error.IsSuccess(), L"ParseConfigSettings");
    }

    void ServiceModelParserTest::ParseAndValidateTargetInformationFile(wstring const & fileName, bool expectValidCurrentInstallation, bool expectValidTargetInstallation)
    {
        Trace.WriteInfo(TestSource, "Parsing target information file {0}", fileName);

        // parse the config settings
        TargetInformationFileDescription desc;
        auto error = desc.FromXml(fileName);
        VERIFY_IS_TRUE(error.IsSuccess(), L"ParseAndValidateTargetInformationFile");
        VERIFY_ARE_EQUAL(expectValidCurrentInstallation, desc.CurrentInstallation.IsValid);
        if (expectValidCurrentInstallation)
        {
            VERIFY_ARE_EQUAL(L"130575528337412373", desc.CurrentInstallation.InstanceId);
            VERIFY_ARE_EQUAL(L"3.1.204.9488", desc.CurrentInstallation.TargetVersion);
            VERIFY_ARE_EQUAL(L"C:\\ProgramData\\Windows Fabric\\Node3\\Fabric\\work\\FabricUpgrade\\WindowsFabric.3.1.204.9488", desc.CurrentInstallation.MSILocation);
            VERIFY_ARE_EQUAL(L"C:\\ProgramData\\Windows Fabric\\Node3\\Fabric\\work\\FabricUpgrade\\ClusterManifest.1.0.xml", desc.CurrentInstallation.ClusterManifestLocation);
            VERIFY_ARE_EQUAL(L"Node3", desc.CurrentInstallation.NodeName);
            VERIFY_IS_TRUE(desc.CurrentInstallation.InfrastructureManifestLocation.empty());
            VERIFY_ARE_EQUAL(L"FabricSetup.exe", desc.CurrentInstallation.UpgradeEntryPointExe);
            VERIFY_ARE_EQUAL(L"/operation:upgrade", desc.CurrentInstallation.UpgradeEntryPointExeParameters);
            VERIFY_ARE_EQUAL(L"FabricSetup.exe", desc.CurrentInstallation.UndoUpgradeEntryPointExe);
            VERIFY_ARE_EQUAL(L"/operation:undoupgrade", desc.CurrentInstallation.UndoUpgradeEntryPointExeParameters);
        }

        VERIFY_ARE_EQUAL(expectValidTargetInstallation, desc.TargetInstallation.IsValid);
        if (expectValidTargetInstallation)
        {
            VERIFY_ARE_EQUAL(L"130575528337412370", desc.TargetInstallation.InstanceId);
            VERIFY_ARE_EQUAL(L"3.1.205.9488", desc.TargetInstallation.TargetVersion);
            VERIFY_ARE_EQUAL(L"C:\\ProgramData\\Windows Fabric\\Node3\\Fabric\\work\\FabricUpgrade\\WindowsFabric.3.1.205.9488.msi", desc.TargetInstallation.MSILocation);
            VERIFY_ARE_EQUAL(L"C:\\ProgramData\\Windows Fabric\\Node3\\Fabric\\work\\FabricUpgrade\\ClusterManifest.1.0.xml", desc.TargetInstallation.ClusterManifestLocation);
            VERIFY_ARE_EQUAL(L"Node3", desc.TargetInstallation.NodeName);
            VERIFY_ARE_EQUAL(L"TestIM", desc.TargetInstallation.InfrastructureManifestLocation);
            VERIFY_IS_TRUE(desc.TargetInstallation.UpgradeEntryPointExe.empty());
            VERIFY_IS_TRUE(desc.TargetInstallation.UpgradeEntryPointExeParameters.empty());
            VERIFY_IS_TRUE(desc.TargetInstallation.UndoUpgradeEntryPointExe.empty());
            VERIFY_IS_TRUE(desc.TargetInstallation.UndoUpgradeEntryPointExeParameters.empty());
        }
    }
}

max_stars_repo_name: AnthonyM/service-fabric

max_issues_repo_name: AnthonyM/service-fabric

max_forks_repo_name: AnthonyM/service-fabric