1
0

[Unit Test] Server version mismatch

[Unit Test] Empty required server version
API and curl changes
This commit is contained in:
Scott E. Graves
2017-02-02 23:51:42 -06:00
parent cc8c8e9c34
commit 352363b25d
9 changed files with 132 additions and 40 deletions

View File

@@ -3,9 +3,10 @@
using namespace Sia::Api; using namespace Sia::Api;
CSiaApi::CSiaApi(const String& host, const std::uint16_t& port) : CSiaApi::CSiaApi(const SiaHostConfig& hostConfig) :
_wallet(new CSiaWallet()) _wallet(new CSiaWallet(_siaCurl))
{ {
_siaCurl.SetHostConfig(hostConfig);
} }
CSiaApi::~CSiaApi() CSiaApi::~CSiaApi()
@@ -13,6 +14,11 @@ CSiaApi::~CSiaApi()
_wallet->Unlock(); _wallet->Unlock();
} }
String CSiaApi::GetServerVersion() const
{
return _siaCurl.GetServerVersion();
}
CSiaWalletPtr CSiaApi::GetWallet() const CSiaWalletPtr CSiaApi::GetWallet() const
{ {
return _wallet; return _wallet;

View File

@@ -1,5 +1,6 @@
#pragma once #pragma once
#include "SiaCommon.h" #include "SiaCommon.h"
#include "SiaCurl.h"
NS_BEGIN(Sia) NS_BEGIN(Sia)
NS_BEGIN(Api) NS_BEGIN(Api)
@@ -7,7 +8,8 @@ NS_BEGIN(Api)
class AFX_EXT_CLASS CSiaApi class AFX_EXT_CLASS CSiaApi
{ {
public: public:
enum class _SiaApiError { enum class _SiaApiError
{
Success, Success,
NotImplemented, NotImplemented,
WalletLocked, WalletLocked,
@@ -19,11 +21,14 @@ public:
{ {
friend CSiaApi; friend CSiaApi;
private: private:
_CSiaWallet(); _CSiaWallet(CSiaCurl& siaCurl);
public: public:
~_CSiaWallet(); ~_CSiaWallet();
private:
CSiaCurl& _siaCurl;
// Properties // Properties
Property(bool, Created, public, private) Property(bool, Created, public, private)
Property(bool, Locked, public, private) Property(bool, Locked, public, private)
@@ -36,22 +41,23 @@ public:
}; };
public: public:
CSiaApi(const String& host, const std::uint16_t& port); CSiaApi(const SiaHostConfig& hostConfig);
public: public:
~CSiaApi(); ~CSiaApi();
private: private:
CSiaCurl _siaCurl;
std::shared_ptr<_CSiaWallet> _wallet; std::shared_ptr<_CSiaWallet> _wallet;
public: public:
std::shared_ptr<_CSiaWallet> GetWallet() const; std::shared_ptr<_CSiaWallet> GetWallet() const;
String GetServerVersion() const;
}; };
typedef CSiaApi::_SiaApiError SiaApiError; typedef CSiaApi::_SiaApiError SiaApiError;
typedef CSiaApi::_CSiaWallet CSiaWallet; typedef CSiaApi::_CSiaWallet CSiaWallet;
typedef std::shared_ptr<CSiaApi::_CSiaWallet> CSiaWalletPtr; typedef std::shared_ptr<CSiaApi::_CSiaWallet> CSiaWalletPtr;
#define API_SUCCESS(x) (x == SiaApiError::Success)
NS_END(2) NS_END(2)

View File

@@ -32,6 +32,9 @@ set_access:\
struct SiaHostConfig struct SiaHostConfig
{ {
std::string HostName; String HostName;
std::uint16_t HostPort; std::uint16_t HostPort;
}; String RequiredVersion;
};
#define API_SUCCESS(t, x) (x == t::Success)

View File

@@ -1,12 +1,13 @@
#include "stdafx.h" #include "stdafx.h"
#include "SiaCurl.h" #include "SiaCurl.h"
#include <curl\curl.h> #include <curl/curl.h>
using namespace Sia::Api; using namespace Sia::Api;
CSiaCurl::CSiaCurl() : CSiaCurl::CSiaCurl() :
_curlHandle(curl_easy_init()) _curlHandle(curl_easy_init())
{ {
SetHostConfig({ "localhost", 9980 }); SetHostConfig({ L"localhost", 9980, L""});
curl_easy_setopt(_curlHandle, CURLOPT_USERAGENT, "Sia-Agent");
} }
CSiaCurl::~CSiaCurl() CSiaCurl::~CSiaCurl()
@@ -14,31 +15,73 @@ CSiaCurl::~CSiaCurl()
curl_easy_cleanup(_curlHandle); curl_easy_cleanup(_curlHandle);
} }
CStringA CSiaCurl::ConstructPath(const CString& relativePath) const SiaCurlError CSiaCurl::_Get(const String& path, json& response) const
{ {
const CStringA ret = CStringA("http://") + GetHostConfig().HostName.c_str() + ":" + std::to_string(GetHostConfig().HostPort).c_str() + CW2A(relativePath); std::string result;
SiaCurlError ret = SiaCurlError::Success;
if (API_SUCCESS(SiaCurlError, ret))
{
curl_easy_setopt(_curlHandle, CURLOPT_URL, ConstructPath(path).c_str());
curl_easy_setopt(_curlHandle, CURLOPT_WRITEFUNCTION, static_cast<size_t(*)(char*, size_t, size_t, void *)>([](char *buffer, size_t size, size_t nitems, void *outstream) -> size_t
{
(*reinterpret_cast<std::string*>(outstream)) += std::string(reinterpret_cast<LPCSTR>(buffer), size * nitems);
return size * nitems;
}));
curl_easy_setopt(_curlHandle, CURLOPT_WRITEDATA, &result);
const CURLcode res = curl_easy_perform(_curlHandle);
if (res != CURLE_OK)
{
ret = SiaCurlError::Failed;
}
response = json::parse(result.c_str());
}
return ret; return ret;
} }
SiaCurlError CSiaCurl::Get(const CString& path, json& response) bool CSiaCurl::CheckVersion(SiaCurlError& error) const
{ {
CStringA result; error = SiaCurlError::InvalidRequiredVersion;
SiaCurlError ret = SiaCurlError::Success; if (GetHostConfig().RequiredVersion.length())
curl_easy_setopt(_curlHandle, CURLOPT_USERAGENT, "Sia-Agent");
curl_easy_setopt(_curlHandle, CURLOPT_URL, static_cast<LPCSTR>(ConstructPath(path)));
curl_easy_setopt(_curlHandle, CURLOPT_WRITEFUNCTION, static_cast<size_t(*)(char*, size_t, size_t, void *)>([](char *buffer, size_t size, size_t nitems, void *outstream) -> size_t
{ {
(*reinterpret_cast<CStringA*>(outstream)) += CString(reinterpret_cast<LPCSTR>(buffer), size * nitems); error = SiaCurlError::NoResponse;
return size * nitems; const String serverVersion = GetServerVersion();
})); if (serverVersion.length())
curl_easy_setopt(_curlHandle, CURLOPT_WRITEDATA, &result); {
const CURLcode res = curl_easy_perform(_curlHandle); error = (serverVersion == GetHostConfig().RequiredVersion) ? SiaCurlError::Success : SiaCurlError::ServerVersionMismatch;
if (res != CURLE_OK) }
{
ret = SiaCurlError::Failed;
} }
response = json::parse((LPCSTR)result); return API_SUCCESS(SiaCurlError, error);
}
std::string CSiaCurl::ConstructPath(const String& relativePath) const
{
const std::string ret = "http://" + std::string(CW2A(GetHostConfig().HostName.c_str()))+ ":" + std::to_string(GetHostConfig().HostPort) + std::string(CW2A(relativePath.c_str()));
return ret;
}
String CSiaCurl::GetServerVersion() const
{
json response;
if (API_SUCCESS(SiaCurlError, _Get(L"/daemon/version", response)))
{
return String(CA2W(response["version"].get<std::string>().c_str()));
}
return L"";
}
SiaCurlError CSiaCurl::Get(const String& path, json& response) const
{
std::string result;
SiaCurlError ret;
if (CheckVersion(ret))
{
ret = _Get(path, response);
}
return ret; return ret;
} }

View File

@@ -12,6 +12,9 @@ public:
enum class _SiaCurlError enum class _SiaCurlError
{ {
Success, Success,
ServerVersionMismatch,
InvalidRequiredVersion,
NoResponse,
Failed Failed
}; };
@@ -27,10 +30,13 @@ private:
Property(SiaHostConfig, HostConfig, public, public) Property(SiaHostConfig, HostConfig, public, public)
private: private:
CStringA ConstructPath(const CString& relativePath) const; std::string ConstructPath(const String& relativePath) const;
_SiaCurlError _Get(const String& path, json& response) const;
bool CheckVersion(_SiaCurlError& error) const;
public: public:
_SiaCurlError Get(const CString& path, json& result); String GetServerVersion() const;
_SiaCurlError Get(const String& path, json& result) const;
}; };
typedef CSiaCurl::_SiaCurlError SiaCurlError; typedef CSiaCurl::_SiaCurlError SiaCurlError;

View File

@@ -3,7 +3,10 @@
using namespace Sia::Api; using namespace Sia::Api;
CSiaApi::_CSiaWallet::_CSiaWallet() CSiaApi::_CSiaWallet::_CSiaWallet(CSiaCurl& siaCurl) :
_siaCurl(siaCurl),
_Created(false),
_Locked(false)
{ {
} }
@@ -28,7 +31,7 @@ SiaApiError CSiaApi::_CSiaWallet::Restore(const String& seed)
SiaApiError CSiaApi::_CSiaWallet::Lock() SiaApiError CSiaApi::_CSiaWallet::Lock()
{ {
SiaApiError error = GetCreated() ? (GetLocked() ? SiaApiError::WalletLocked : SiaApiError::Success) : SiaApiError::WalletNotCreated; SiaApiError error = GetCreated() ? (GetLocked() ? SiaApiError::WalletLocked : SiaApiError::Success) : SiaApiError::WalletNotCreated;
if (API_SUCCESS(error)) if (API_SUCCESS(SiaApiError, error))
{ {
} }
@@ -38,7 +41,7 @@ SiaApiError CSiaApi::_CSiaWallet::Lock()
SiaApiError CSiaApi::_CSiaWallet::Unlock() SiaApiError CSiaApi::_CSiaWallet::Unlock()
{ {
SiaApiError error = GetCreated() ? (GetLocked() ? SiaApiError::Success : SiaApiError::WalletUnlocked) : SiaApiError::WalletNotCreated; SiaApiError error = GetCreated() ? (GetLocked() ? SiaApiError::Success : SiaApiError::WalletUnlocked) : SiaApiError::WalletNotCreated;
if (API_SUCCESS(error)) if (API_SUCCESS(SiaApiError, error))
{ {
} }

View File

@@ -29,6 +29,12 @@ SOFTWARE.
#ifndef NLOHMANN_JSON_HPP #ifndef NLOHMANN_JSON_HPP
#define NLOHMANN_JSON_HPP #define NLOHMANN_JSON_HPP
#ifdef _WIN32
#ifdef max
#undef max
#endif
#endif
#include <algorithm> // all_of, for_each, transform #include <algorithm> // all_of, for_each, transform
#include <array> // array #include <array> // array
#include <cassert> // assert #include <cassert> // assert

View File

@@ -13,12 +13,31 @@ namespace UnitTests
TEST_METHOD(GetBasicTest) TEST_METHOD(GetBasicTest)
{ {
CSiaCurl s; CSiaCurl s;
s.SetHostConfig({ "localhost", 9980 }); s.SetHostConfig({ L"localhost", 9980, L"1.1.0" });
json result; json result;
SiaCurlError err = s.Get(L"/daemon/version", result); SiaCurlError err = s.Get(L"/daemon/version", result);
Assert::IsTrue(err == SiaCurlError::Success); Assert::IsTrue(err == SiaCurlError::Success);
Assert::IsTrue(result["version"].is_string()); }
TEST_METHOD(EmptyHostConfigRequiredVersion)
{
CSiaCurl s;
s.SetHostConfig({ L"localhost", 9980, L"" });
json result;
SiaCurlError err = s.Get(L"/daemon/version", result);
Assert::IsTrue(err == SiaCurlError::InvalidRequiredVersion);
}
TEST_METHOD(ServerVersionDoesNotMatchRequiredVersion)
{
CSiaCurl s;
s.SetHostConfig({ L"localhost", 9980, L"ouaoeuaoeuaoeu" });
json result;
SiaCurlError err = s.Get(L"/daemon/version", result);
Assert::IsTrue(err == SiaCurlError::ServerVersionMismatch);
} }
}; };

View File

@@ -45,7 +45,7 @@
<UseDebugLibraries>true</UseDebugLibraries> <UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset> <PlatformToolset>v140</PlatformToolset>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
<UseOfMfc>false</UseOfMfc> <UseOfMfc>Dynamic</UseOfMfc>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType> <ConfigurationType>DynamicLibrary</ConfigurationType>
@@ -53,7 +53,7 @@
<PlatformToolset>v140</PlatformToolset> <PlatformToolset>v140</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization> <WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
<UseOfMfc>false</UseOfMfc> <UseOfMfc>Dynamic</UseOfMfc>
</PropertyGroup> </PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings"> <ImportGroup Label="ExtensionSettings">
@@ -90,7 +90,7 @@
<PrecompiledHeader>Use</PrecompiledHeader> <PrecompiledHeader>Use</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel> <WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization> <Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\SiaDrive.Api;$(VCInstallDir)UnitTest\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>..\SiaDrive.Api;..\SiaDrive.Api;$(VCInstallDir)UnitTest\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>WIN32;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<UseFullPaths>true</UseFullPaths> <UseFullPaths>true</UseFullPaths>
</ClCompile> </ClCompile>
@@ -106,7 +106,7 @@
<PrecompiledHeader>Use</PrecompiledHeader> <PrecompiledHeader>Use</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel> <WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization> <Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>$(VCInstallDir)UnitTest\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>..\SiaDrive.Api;$(VCInstallDir)UnitTest\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<UseFullPaths>true</UseFullPaths> <UseFullPaths>true</UseFullPaths>
</ClCompile> </ClCompile>
@@ -122,7 +122,7 @@
<Optimization>MaxSpeed</Optimization> <Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking> <FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions> <IntrinsicFunctions>true</IntrinsicFunctions>
<AdditionalIncludeDirectories>..\SiaDrive.Api;$(VCInstallDir)UnitTest\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>..\SiaDrive.Api;..\SiaDrive.Api;$(VCInstallDir)UnitTest\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>WIN32;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<UseFullPaths>true</UseFullPaths> <UseFullPaths>true</UseFullPaths>
</ClCompile> </ClCompile>
@@ -142,7 +142,7 @@
<Optimization>MaxSpeed</Optimization> <Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking> <FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions> <IntrinsicFunctions>true</IntrinsicFunctions>
<AdditionalIncludeDirectories>$(VCInstallDir)UnitTest\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>..\SiaDrive.Api;$(VCInstallDir)UnitTest\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<UseFullPaths>true</UseFullPaths> <UseFullPaths>true</UseFullPaths>
</ClCompile> </ClCompile>