diff --git a/.gitignore b/.gitignore
index d25e675..d69e867 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,6 +4,7 @@
*.user
*.userosscache
*.sln.docstates
+.idea
packages
.DS_Store
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 91cf397..33fb641 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -32,9 +32,14 @@
- 支持全局二级索引(GlobalIndex)
- 支持原子增
-## 版本号 5.0.0 日期:2020/08/15
+## 版本号 5.0.0 日期:2022/08/15
### 变更内容
- 多元索引支持统计聚合功能(Aggregation & GroupBy)
- 多元索引支持创建虚拟列、日期列
- 多元索引支持索引TTL
- 支持SQL查询
+
+## 版本号 6.0.0 日期:2022/08/23
+### 变更内容
+- 支持netstandard2.0框架
+- 兼容net40框架
diff --git a/README.md b/README.md
index 98cabcd..2b46cb5 100644
--- a/README.md
+++ b/README.md
@@ -9,11 +9,12 @@
- 阿里云表格存储是构建在阿里云飞天分布式系统之上的NoSQL数据存储服务,提供海量结构化数据的存储和实时访问。
## 版本
- - 当前版本:5.0.0
+ - 当前版本:6.0.0
## 运行环境
### Windows
- 适用于`.NET 4.0` 及以上版本
+ - 适用于`.NETSTANDARD2.0`及以上版本
- 适用于`Visual Studio 2010`及以上版本
## 注意事项
diff --git a/aliyun-tablestore-csharp-sdk.sln b/aliyun-tablestore-csharp-sdk.sln
index cbc68aa..b0022ce 100644
--- a/aliyun-tablestore-csharp-sdk.sln
+++ b/aliyun-tablestore-csharp-sdk.sln
@@ -3,13 +3,18 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.32630.194
MinimumVisualStudioVersion = 10.0.40219.1
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "aliyun-tablestore-sdk", "sdk\aliyun-tablestore-sdk.csproj", "{AB5EFCA2-53A9-42B5-861E-3FD6F865036B}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "aliyun-tablestore-sdk-test", "test\aliyun-tablestore-sdk-test.csproj", "{F30E0874-399A-4FBD-B72B-74EE36B31AF6}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "aliyun-tablestore-sdk", "sdk\aliyun-tablestore-sdk.csproj", "{AB5EFCA2-53A9-42B5-861E-3FD6F865036B}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "aliyun-tablestore-sdk-sample", "sample\aliyun-tablestore-sdk-sample.csproj", "{D151C869-BC8F-4465-9460-5103A25D21E9}"
+ ProjectSection(ProjectDependencies) = postProject
+ {AB5EFCA2-53A9-42B5-861E-3FD6F865036B} = {AB5EFCA2-53A9-42B5-861E-3FD6F865036B}
+ EndProjectSection
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "aliyun-tablestore-sdk-netcore-sample", "sample\aliyun-tablestore-sdk-netcore-sample.csproj", "{19084237-90AD-4BDF-B0A9-B4A51B6931DA}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "aliyun-tablestore-sdk-netcore-test", "test\aliyun-tablestore-sdk-netcore-test.csproj", "{629D7B33-F623-4663-A8F1-0B9280B781FC}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "internalTest", "internalTest\internalTest.csproj", "{BBC62040-3F72-419D-BF9E-606DE4B8BF1E}"
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "aliyun-tablestore-sdk-test", "test\aliyun-tablestore-sdk-test.csproj", "{9D7540C1-72D3-496E-AB6E-29534A06C037}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -21,18 +26,22 @@ Global
{AB5EFCA2-53A9-42B5-861E-3FD6F865036B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{AB5EFCA2-53A9-42B5-861E-3FD6F865036B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{AB5EFCA2-53A9-42B5-861E-3FD6F865036B}.Release|Any CPU.Build.0 = Release|Any CPU
- {F30E0874-399A-4FBD-B72B-74EE36B31AF6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {F30E0874-399A-4FBD-B72B-74EE36B31AF6}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {F30E0874-399A-4FBD-B72B-74EE36B31AF6}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {F30E0874-399A-4FBD-B72B-74EE36B31AF6}.Release|Any CPU.Build.0 = Release|Any CPU
{D151C869-BC8F-4465-9460-5103A25D21E9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D151C869-BC8F-4465-9460-5103A25D21E9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D151C869-BC8F-4465-9460-5103A25D21E9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D151C869-BC8F-4465-9460-5103A25D21E9}.Release|Any CPU.Build.0 = Release|Any CPU
- {BBC62040-3F72-419D-BF9E-606DE4B8BF1E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {BBC62040-3F72-419D-BF9E-606DE4B8BF1E}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {BBC62040-3F72-419D-BF9E-606DE4B8BF1E}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {BBC62040-3F72-419D-BF9E-606DE4B8BF1E}.Release|Any CPU.Build.0 = Release|Any CPU
+ {19084237-90AD-4BDF-B0A9-B4A51B6931DA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {19084237-90AD-4BDF-B0A9-B4A51B6931DA}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {19084237-90AD-4BDF-B0A9-B4A51B6931DA}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {19084237-90AD-4BDF-B0A9-B4A51B6931DA}.Release|Any CPU.Build.0 = Release|Any CPU
+ {629D7B33-F623-4663-A8F1-0B9280B781FC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {629D7B33-F623-4663-A8F1-0B9280B781FC}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {629D7B33-F623-4663-A8F1-0B9280B781FC}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {629D7B33-F623-4663-A8F1-0B9280B781FC}.Release|Any CPU.Build.0 = Release|Any CPU
+ {9D7540C1-72D3-496E-AB6E-29534A06C037}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {9D7540C1-72D3-496E-AB6E-29534A06C037}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {9D7540C1-72D3-496E-AB6E-29534A06C037}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {9D7540C1-72D3-496E-AB6E-29534A06C037}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/sample/App.config b/sample/App.config
deleted file mode 100644
index 74ade9d..0000000
--- a/sample/App.config
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
-
-
-
diff --git a/sample/Properties/AssemblyInfo.cs b/sample/Properties/AssemblyInfo.cs
index c9e7d2f..edf2037 100644
--- a/sample/Properties/AssemblyInfo.cs
+++ b/sample/Properties/AssemblyInfo.cs
@@ -6,11 +6,11 @@
// 控制。更改这些特性值可修改
// 与程序集关联的信息。
[assembly: AssemblyTitle("Aliyun.TableStore.Samples")]
-[assembly: AssemblyDescription("Aliyun TableStore SDK Samples for .NET.")]
+[assembly: AssemblyDescription("Aliyun TableStore SDK Samples for .NETSTANDARD2.0 and .NET40.")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Alibaba Cloud Computing")]
[assembly: AssemblyProduct("Aliyun.TableStore")]
-[assembly: AssemblyCopyright("Copyright (c) 2009-2016 aliyun.com")]
+[assembly: AssemblyCopyright("Copyright (c) 2009-2022 aliyun.com")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
@@ -32,5 +32,5 @@
//可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值,
// 方法是按如下所示使用“*”: :
// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("3.1.0")]
-[assembly: AssemblyFileVersion("3.1.0")]
+[assembly: AssemblyVersion("6.0.0")]
+[assembly: AssemblyFileVersion("6.0.0")]
diff --git a/sample/Samples/SearchIndexSample.cs b/sample/Samples/SearchIndexSample.cs
index ee10225..8eb82ac 100644
--- a/sample/Samples/SearchIndexSample.cs
+++ b/sample/Samples/SearchIndexSample.cs
@@ -770,11 +770,11 @@ public static void GroupBy(OTSClient otsClient)
groupByGeoDistance.FieldName = Geo_type_col;
groupByGeoDistance.GroupByName = "groupByGeoDistance";
groupByGeoDistance.Origin = new GeoPoint(0, 0);
- groupByGeoDistance.Ranges = new List()
+ groupByGeoDistance.Ranges = new List()
{
- new Range(double.MinValue, 100.0),
- new Range(100.0, 1000.0),
- new Range(1000.0, double.MaxValue)
+ new DataModel.Search.GroupBy.Range(double.MinValue, 100.0),
+ new DataModel.Search.GroupBy.Range(100.0, 1000.0),
+ new DataModel.Search.GroupBy.Range(1000.0, double.MaxValue)
};
GroupByHistogram groupByHistogram = new GroupByHistogram();
@@ -787,11 +787,11 @@ public static void GroupBy(OTSClient otsClient)
GroupByRange groupByRange = new GroupByRange();
groupByRange.GroupByName = "groupByRange";
groupByRange.FieldName = Long_type_col;
- groupByRange.Ranges = new List()
+ groupByRange.Ranges = new List()
{
- new Range(0 , 5),
- new Range(5,10),
- new Range(10, double.MaxValue)
+ new DataModel.Search.GroupBy.Range(0 , 5),
+ new DataModel.Search.GroupBy.Range(5,10),
+ new DataModel.Search.GroupBy.Range(10, double.MaxValue)
};
GroupByResults results = GroupByRunner(otsClient, groupByField, groupByFilter, groupByGeoDistance, groupByHistogram, groupByRange);
diff --git a/sample/aliyun-tablestore-sdk-netcore-sample.csproj b/sample/aliyun-tablestore-sdk-netcore-sample.csproj
new file mode 100644
index 0000000..3299ca1
--- /dev/null
+++ b/sample/aliyun-tablestore-sdk-netcore-sample.csproj
@@ -0,0 +1,55 @@
+
+
+
+ Exe
+ netcoreapp3.1
+ False
+ False
+ false
+ false
+ false
+ false
+ false
+ false
+ false
+ Properties
+ Aliyun.OTS.Samples
+
+
+ Aliyun.OSS.Samples
+ Aliyun.OTS.Samples.Samples.SearchIndexSample
+
+
+ 5
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/sample/aliyun-tablestore-sdk-sample.csproj b/sample/aliyun-tablestore-sdk-sample.csproj
index d228278..3267e14 100644
--- a/sample/aliyun-tablestore-sdk-sample.csproj
+++ b/sample/aliyun-tablestore-sdk-sample.csproj
@@ -1,19 +1,16 @@
-
+
Debug
AnyCPU
{D151C869-BC8F-4465-9460-5103A25D21E9}
Exe
- Properties
Aliyun.OTS.Samples
- Aliyun.TableStore.Sample
+ Aliyun.TableStore.Net40.Sample
+ v4.0
512
- true
-
- 8.0.30703
- 2.0
+ true
publish\
true
Disk
@@ -26,11 +23,14 @@
true
0
1.0.0.%2a
- false
false
true
+ 8.0.30703
+ 2.0
+ notexistfile
+ AnyCPU
true
full
false
@@ -49,11 +49,10 @@
4
- Aliyun.OTS.Samples.Program
+ Aliyun.OTS.Samples.Samples.SearchIndexSample
-
@@ -69,34 +68,25 @@
-
-
-
-
-
- ..\packages\Newtonsoft.Json.11.0.2\lib\net40\Newtonsoft.Json.dll
+
+ ..\packages\Newtonsoft.Json.13.0.1\lib\net40\Newtonsoft.Json.dll
+
+
+
+
+
+
+
+
+
- {AB5EFCA2-53A9-42B5-861E-3FD6F865036B}
+ {ab5efca2-53a9-42b5-861e-3fd6f865036b}
aliyun-tablestore-sdk
-
-
- False
- .NET Framework 3.5 SP1
- false
-
-
-
\ No newline at end of file
diff --git a/sample/packages.config b/sample/packages.config
index b22ea6b..d9261b8 100644
--- a/sample/packages.config
+++ b/sample/packages.config
@@ -1,4 +1,4 @@
-
+
\ No newline at end of file
diff --git a/sdk/Properties/AssemblyInfo.cs b/sdk/Properties/AssemblyInfo.cs
index 48335ae..b1cc9ce 100644
--- a/sdk/Properties/AssemblyInfo.cs
+++ b/sdk/Properties/AssemblyInfo.cs
@@ -6,11 +6,11 @@
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("Aliyun.TableStore")]
-[assembly: AssemblyDescription("Aliyun Table Store SDK for .NET")]
+[assembly: AssemblyDescription("Aliyun Table Store SDK for .NETSTANDARD2.0 and .NET40")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Alibaba Cloud Computing")]
[assembly: AssemblyProduct("Aliyun.TableStore")]
-[assembly: AssemblyCopyright("Copyright (c) 2009-2018 aliyun.com")]
+[assembly: AssemblyCopyright("Copyright (c) 2009-2022 aliyun.com")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
diff --git a/sdk/aliyun-tablestore-sdk.csproj b/sdk/aliyun-tablestore-sdk.csproj
index 398e36e..3f7bb3d 100644
--- a/sdk/aliyun-tablestore-sdk.csproj
+++ b/sdk/aliyun-tablestore-sdk.csproj
@@ -1,349 +1,37 @@
-
-
-
+
- Debug
- AnyCPU
- {AB5EFCA2-53A9-42B5-861E-3FD6F865036B}
+ netstandard2.0;net40
Library
- Properties
- Aliyun.TableStore
- 512
- 8.0.30703
- 2.0
- v4.0
-
+ Aliyun.TableStore.SDK
+ Aliyun.TableStore.SDK
+ aliyun
+ 6.0.0
+ Aliyun Table Store SDK for .NetCore and .NETFrameWork
+ Copyright (c) 2009-2022 aliyun.com
+ Support NetStandard2.0; Compatible NetFrameWork4.0.
+ https://github.com/aliyun/aliyun-tablestore-csharp-sdk
+ Apache-2.0
+ false
+ 7
+ Aliyun.OTS
-
- true
- full
- false
- bin\Debug\
- DEBUG;TRACE
- prompt
- 4
- AnyCPU
- 4
- false
-
-
- pdbonly
- true
- bin\Release\
- TRACE
- prompt
- 4
- 4
- false
+
+ $(DefineConstants);UNSAFE_BYTEBUFFER;ENABLE_SPAN_T
-
- ..\packages\KdSoft.FlatBuffers.1.12.0\lib\net35\Google.FlatBuffers.dll
-
-
-
- ..\packages\Google.ProtocolBuffers.2.4.1.555\lib\net40\Google.ProtocolBuffers.dll
-
-
- ..\packages\Google.ProtocolBuffers.2.4.1.555\lib\net40\Google.ProtocolBuffers.Serialization.dll
-
-
-
- ..\packages\Microsoft.Net.Http.2.0.20710.0\lib\net40\System.Net.Http.dll
-
-
- ..\packages\Microsoft.Net.Http.2.0.20710.0\lib\net40\System.Net.Http.WebRequest.dll
-
-
-
-
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+ 4.3.4
+
-
-
-
-
-
-
+
+
+ 2.0.20710
+
-
-
-
\ No newline at end of file
diff --git a/sdk/packages.config b/sdk/packages.config
deleted file mode 100644
index 7cfb81e..0000000
--- a/sdk/packages.config
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/test/UnitTest/OTSUnitTestBase.cs b/test/UnitTest/OTSUnitTestBase.cs
index d3008bb..9fe9597 100644
--- a/test/UnitTest/OTSUnitTestBase.cs
+++ b/test/UnitTest/OTSUnitTestBase.cs
@@ -1,1214 +1,1214 @@
-/*
- * Trade secret of Alibaba Group R&D.
- * Copyright (c) 2015 Alibaba Group R&D.
- *
- * All rights reserved. This notice is intended as a precaution against
- * inadvertent publication and does not imply publication or any waiver
- * of confidentiality. The year included in the foregoing notice is the
- * year of creation of the work.
- *
- */
-
-using System;
-using System.Collections.Generic;
-using System.Threading;
-using System.Net;
-using System.IO;
-using System.Security.Cryptography;
-using NUnit.Framework;
-using Aliyun.OTS.DataModel;
-using Aliyun.OTS.Response;
-using Aliyun.OTS.Request;
-using PB = com.alicloud.openservices.tablestore.core.protocol;
-using Aliyun.OTS.DataModel.ConditionalUpdate;
-using Aliyun.OTS.DataModel.Search;
-
-namespace Aliyun.OTS.UnitTest
-{
- class APITestContext
- {
- public string tableName;
- public PrimaryKeySchema pkSchema;
- public CapacityUnit reservedThroughput;
- public PrimaryKey primaryKey;
- public AttributeColumns attribute;
- public UpdateOfAttribute updateOfAttributeForPut;
- public UpdateOfAttribute updateOfAttributeForDelete;
- public Condition condition;
- public GetRangeDirection direction = GetRangeDirection.Forward;
- public PrimaryKey startPrimaryKey;
- public PrimaryKey endPrimaryKey;
- public HashSet columnsToGet;
- public int? limit;
- public CapacityUnit putRowConsumed;
- public CapacityUnit getRowConsumed;
- public CapacityUnit updateRowConsumed;
- public CapacityUnit deleteRowConsumed;
- public CapacityUnit getRangeConsumed;
- public Dictionary expectedFailure;
- public string allFailedMessage;
- }
-
- class LogToFileHandler : OTSDefaultLogHandler
- {
- public static new void DefaultErrorLogHandler(string message)
- {
- var dateString = GetDateTimeString();
- using (StreamWriter w = File.AppendText("./log.txt"))
- {
- w.Write("OTSClient ERROR {0} {1}", dateString, message);
- }
- }
-
- public static new void DefaultDebugLogHandler(string message)
- {
- var dateString = GetDateTimeString();
- using (StreamWriter w = File.AppendText("./log.txt"))
- {
- w.Write("OTSClient DEBUG {0} {1}", dateString, message);
- }
- }
- }
-
- [TestFixture]
- class OTSUnitTestBase
- {
- public string TestEndPoint = Test.Config.Endpoint;
- public string TestAccessKeyID = Test.Config.AccessKeyId;
- public string TestAccessKeySecret = Test.Config.AccessKeySecret;
- public string TestInstanceName = Test.Config.InstanceName;
- public OTSClient OTSClient;
-
- // Predefined test data
- public static string TestTableName = "SearchQueryTest";
- public static string TestSearchIndexName = "SearchQueryTestIndex";
- public static PrimaryKey PrimaryKeyWith4Columns;
- public static PrimaryKey MinPrimaryKeyWith4Columns;
- public static PrimaryKey MaxPrimaryKeyWith4Columns;
- public static AttributeColumns AttributeWith5Columns;
- public static List PrimaryKeyList;
- public static List AttributeColumnsList;
-
- public APITestContext TestContext;
-
- [SetUp]
- public void Setup()
- {
- Thread.Sleep(1000);
-
- var clientConfig = new OTSClientConfig(
- TestEndPoint,
- TestAccessKeyID,
- TestAccessKeySecret,
- TestInstanceName
- );
-
- Console.WriteLine("Endpoint: {0}", TestEndPoint);
- Console.WriteLine("TestAccessKeyID: {0}", TestAccessKeyID);
- Console.WriteLine("TestAccessKeySecret: {0}", TestAccessKeySecret);
- Console.WriteLine("TestInstanceName: {0}", TestInstanceName);
- clientConfig.OTSDebugLogHandler = LogToFileHandler.DefaultDebugLogHandler;
- clientConfig.OTSErrorLogHandler = LogToFileHandler.DefaultErrorLogHandler;
- OTSClient = new OTSClient(clientConfig);
- OTSClientTestHelper.Reset();
-
- // 删除数据表
- foreach (var tableName in OTSClient.ListTable(new ListTableRequest()).TableNames)
- {
- try
- {
- ListSearchIndexRequest listSearchIndexRequest = new ListSearchIndexRequest(tableName);
- ListSearchIndexResponse listSearchIndexResponse = OTSClient.ListSearchIndex(listSearchIndexRequest);
-
- foreach (SearchIndexInfo indexInfo in listSearchIndexResponse.IndexInfos)
- {
- DeleteSearchIndexRequest deleteSearchIndexRequest = new DeleteSearchIndexRequest(tableName, indexInfo.IndexName);
- OTSClient.DeleteSearchIndex(deleteSearchIndexRequest);
- }
-
- Thread.Sleep(1000);
-
- DeleteTable(tableName);
- }
- catch
- {
- Console.WriteLine("Delete Index or Table failed!");
- }
- }
-
- PrimaryKeyWith4Columns = new PrimaryKey
- {
- { "PK0", new ColumnValue("ABC") },
- { "PK1", new ColumnValue("DEF") },
- { "PK2", new ColumnValue(123) },
- { "PK3", new ColumnValue(456) }
- };
-
- MinPrimaryKeyWith4Columns = new PrimaryKey
- {
- { "PK0", ColumnValue.INF_MIN },
- { "PK1", new ColumnValue("DEF") },
- { "PK2", new ColumnValue(123) },
- { "PK3", new ColumnValue(456) }
- };
-
- MaxPrimaryKeyWith4Columns = new PrimaryKey
- {
- { "PK0", ColumnValue.INF_MAX },
- { "PK1", new ColumnValue("DEF") },
- { "PK2", new ColumnValue(123) },
- { "PK3", new ColumnValue(456) }
- };
-
- AttributeWith5Columns = new AttributeColumns
- {
- { "Col0", new ColumnValue("ABC") },
- { "Col1", new ColumnValue(123) },
- { "Col2", new ColumnValue(3.14) },
- { "Col3", new ColumnValue(true) },
- { "Col4", new ColumnValue(new byte[] { 0x20, 0x20 }) }
- };
-
- PrimaryKeyList = new List();
- AttributeColumnsList = new List();
-
-
- for (int i = 0; i < 1000; i++)
- {
- PrimaryKeyList.Add(GetPredefinedPrimaryKeyWith4PK(i));
- AttributeColumnsList.Add(GetPredefinedAttributeWith5PK(i));
- }
-
- // 创建数据表
- Thread.Sleep(2000);
- var primaryKeySchema = new PrimaryKeySchema
- {
- {"pk0" , ColumnValueType.String},
- {"pk1" , ColumnValueType.Integer}
- };
-
- TableMeta tableMeta = new TableMeta(TestTableName, primaryKeySchema);
-
- tableMeta.DefinedColumnSchema = new DefinedColumnSchema{
- { "col1" , DefinedColumnType.STRING},
- { "col2" , DefinedColumnType.STRING},
- };
-
- // TableOptions
- TableOptions tableOptions = new TableOptions();
- tableOptions.AllowUpdate = false;
-
- // 创建二级索引
- IndexMeta indexMeta = new IndexMeta(TestTableName + "index");
- indexMeta.PrimaryKey = new List() { "col1" };
- indexMeta.DefinedColumns = new List() { "col2" };
-
- List indexMetas = new List() { };
- indexMetas.Add(indexMeta);
-
- // ִ执行创建表操作
- CapacityUnit reservedThroughput = new CapacityUnit(0, 0);
- CreateTableRequest request = new CreateTableRequest(tableMeta, reservedThroughput);
- request.TableOptions = tableOptions;
- CreateTableResponse createTableResponse = OTSClient.CreateTable(request);
- Console.WriteLine("Create table succeed!");
-
- // 创建多元索引
- CreateSearchIndexRequest createSearchIndexRequest = new CreateSearchIndexRequest(TestTableName, TestSearchIndexName);
- List fieldSchemas = new List {
- new FieldSchema("col1" , FieldType.KEYWORD){
- index = true,
- EnableSortAndAgg = true
- },
- new FieldSchema("pk1" , FieldType.LONG) { index = true, EnableSortAndAgg = true},
- new FieldSchema("col2" , FieldType.TEXT) {
- index = true ,
- Analyzer=Analyzer.MaxWord
- },
- new FieldSchema("DATE_col" , FieldType.DATE){
- index = true,
- DateFormats = new List(){
- "yyyy-MM-dd'T'HH:mm:ss.SSSSSS",
- "yyyy-MM-dd'T'HH:mm:ss.SSS"
- }
- }
- };
-
- createSearchIndexRequest.IndexSchame = new IndexSchema()
- {
- FieldSchemas = fieldSchemas,
- IndexSort = new OTS.DataModel.Search.Sort.Sort(
- new List
- {
- new OTS.DataModel.Search.Sort.FieldSort("pk1", OTS.DataModel.Search.Sort.SortOrder.ASC)
- })
- };
-
- CreateSearchIndexResponse createSearchIndexResponse = OTSClient.CreateSearchIndex(createSearchIndexRequest);
-
- Console.WriteLine("Create Search Index succeed!");
- }
-
- public PrimaryKey GetPredefinedPrimaryKeyWith4PK(int index)
- {
- var primaryKey = new PrimaryKey
- {
- { "PK0", new ColumnValue("ABC" + index) },
- { "PK1", new ColumnValue("DEF" + index) },
- { "PK2", new ColumnValue(123 + index) },
- { "PK3", new ColumnValue(456 + index) }
- };
- return primaryKey;
- }
-
- public AttributeColumns GetPredefinedAttributeWith5PK(int index)
- {
- var attribute = new AttributeColumns
- {
- { "Col0", new ColumnValue("ABC" + index) },
- { "Col1", new ColumnValue(123 + index) },
- { "Col2", new ColumnValue(3.14 + index) },
- { "Col3", new ColumnValue(index % 2 == 0) },
- { "Col4", new ColumnValue(new byte[] { 0x20, 0x20 }) }
- };
- return attribute;
- }
-
- public static void WaitForTableReady()
- {
- Thread.Sleep(2 * 1000);
- }
-
- public static void AssertColumns(Dictionary expect, Dictionary actual, HashSet columnsToGet = null)
- {
- if (columnsToGet != null && columnsToGet.Count != 0)
- {
- var expectReal = new Dictionary();
-
- foreach (var columnName in columnsToGet)
- {
- if (expect.ContainsKey(columnName))
- {
- expectReal.Add(columnName, expect[columnName]);
- }
- }
-
- expect = expectReal;
- }
-
- if (expect == null && actual == null)
- {
- return;
- }
-
-
- Assert.IsTrue(expect != null && actual != null, "expect and actual should NOT be null");
-
- Assert.AreEqual(expect.Count, actual.Count);
-
- foreach (var expectValue in expect)
- {
- Assert.IsTrue(actual.ContainsKey(expectValue.Key));
- var actualItem = actual[expectValue.Key];
- var expectItem = expectValue.Value;
-
- var result = expectItem.CompareTo(actualItem);
-
- Assert.IsTrue(result == 0, "columnValue Not equal, expect:" + expectItem + ", actual:" + actualItem);
- }
- }
-
- public static void AssertPrimaryKey(PrimaryKey expect, PrimaryKey actual, HashSet columnsToGet = null)
- {
- AssertColumns(expect, actual, columnsToGet);
- }
-
- public static void AssertAttribute(AttributeColumns expect, AttributeColumns actual, HashSet columnsToGet = null)
- {
- AssertColumns(expect, actual, columnsToGet);
- }
-
- public static void AssertAttribute(AttributeColumns expect, Column[] actual, HashSet columnsToGet = null)
- {
- AssertColumns(expect, AttributeColumns.ParseColumnArray(actual), columnsToGet);
- }
-
- public static void AssertOTSServerException(OTSServerException expect, OTSServerException actual)
- {
- if (expect.APIName != actual.APIName ||
- expect.HttpStatusCode != actual.HttpStatusCode ||
- expect.ErrorCode != actual.ErrorCode ||
- expect.ErrorMessage != actual.ErrorMessage)
- {
-
- throw new AssertionException(String.Format(
- "OTSServerException Assert Failed. expect: {0} actual {1}",
- expect.Message, actual.Message
- ));
- }
- }
-
- public void CreateTestTable(string tableName, PrimaryKeySchema schema, CapacityUnit reservedThroughput, bool waitFlag = true)
- {
- var tableMeta = new TableMeta(tableName, schema);
-
- var tableOptions = new TableOptions
- {
- MaxVersions = 10,
- TimeToLive = -1
- };
-
- var request = new CreateTableRequest(tableMeta, reservedThroughput)
- {
- TableOptions = tableOptions
- };
-
- OTSClient.CreateTable(request);
-
- if (waitFlag)
- {
- WaitForTableReady();
- }
- }
-
- public void CreateTestTableWith2PK()
- {
- var schema = new PrimaryKeySchema
- {
- { "PK0", ColumnValueType.String },
- { "PK1", ColumnValueType.Integer }
- };
-
- CreateTestTable(TestTableName, schema, new CapacityUnit(0, 0));
- }
-
- public void CreateTestTableWith4PK(CapacityUnit reservedThroughput = null, string tableName = null)
- {
- if (reservedThroughput == null)
- {
- reservedThroughput = new CapacityUnit(0, 0);
- }
-
- var schema = new PrimaryKeySchema
- {
- { "PK0", ColumnValueType.String },
- { "PK1", ColumnValueType.String },
- { "PK2", ColumnValueType.Integer },
- { "PK3", ColumnValueType.Integer }
- };
-
- if (string.IsNullOrEmpty(tableName))
- {
- CreateTestTable(TestTableName, schema, reservedThroughput);
- }
- else
- {
- CreateTestTable(tableName, schema, reservedThroughput);
- }
- }
-
- public static void AssertCapacityUnit(CapacityUnit expect, CapacityUnit actual)
- {
- if (expect == null && actual == null)
- {
- return;
- }
-
- if (expect == null || actual == null)
- {
- Assert.Fail();
- }
-
- Assert.AreEqual(expect.Read, actual.Read, "CapacityUnit Read not Matched");
- Assert.AreEqual(expect.Write, actual.Write, "CapacityUnit Write not Matched");
- }
-
- ///
- /// Puts the single row.
- ///
- /// Table name.
- /// Primary key.
- /// Attributes.
- public void PutSingleRow(string tableName, PrimaryKey primaryKey, AttributeColumns attributes)
- {
- var request = new PutRowRequest(tableName, new Condition(RowExistenceExpectation.IGNORE));
- request.RowPutChange.PrimaryKey = primaryKey;
- foreach (var attribute in attributes)
- {
- request.RowPutChange.AddColumn(attribute.Key, attribute.Value);
- }
-
- OTSClient.PutRow(request);
- }
-
- public void CheckSingleRow(string tableName, PrimaryKey primaryKey,
- AttributeColumns attribute,
- CapacityUnit expectCapacityUnitConsumed = null,
- HashSet columnsToGet = null,
- bool isEmpty = false,
- IColumnCondition condition = null)
- {
- var request = new GetRowRequest(tableName, primaryKey, columnsToGet, condition);
-
- var response = OTSClient.GetRow(request);
-
- PrimaryKey primaryKeyToExpect;
- AttributeColumns attributeToExpect;
-
- if (isEmpty)
- {
- primaryKeyToExpect = new PrimaryKey();
- attributeToExpect = new AttributeColumns();
- }
- else if (columnsToGet == null || columnsToGet.Count == 0)
- {
- primaryKeyToExpect = primaryKey;
- attributeToExpect = attribute;
- }
- else
- {
- primaryKeyToExpect = primaryKey;
- attributeToExpect = new AttributeColumns();
- foreach (var columnName in columnsToGet)
- {
- if (attribute.ContainsKey(columnName))
- {
- attributeToExpect.Add(columnName, attribute[columnName]);
- }
- }
- }
-
- AssertColumns(primaryKeyToExpect, response.PrimaryKey);
- AssertColumns(attributeToExpect, response.Attribute);
-
- if (expectCapacityUnitConsumed != null)
- {
- AssertCapacityUnit(expectCapacityUnitConsumed, response.ConsumedCapacityUnit);
- }
- }
-
- public static BatchWriteRowResponseForOneTable GetNewBatchWriteRowResponseForOneTable()
- {
- var item = new BatchWriteRowResponseForOneTable
- {
- Responses = new List()
- };
-
- return item;
- }
-
- private void AssertOneOperationInBatchWriteRowResponse(
- IList expect, IList actual)
- {
- Assert.AreEqual(expect.Count, actual.Count);
-
- for (int i = 0; i < expect.Count; i++)
- {
- var expectItem = expect[i];
- var actualItem = actual[i];
-
- Assert.AreEqual(expectItem.IsOK, actualItem.IsOK);
- Assert.AreEqual(expectItem.ErrorCode, actualItem.ErrorCode);
- Assert.AreEqual(expectItem.ErrorMessage, actualItem.ErrorMessage);
- Assert.AreEqual(expectItem.TableName, actualItem.TableName);
- Assert.AreEqual(expectItem.Index, actualItem.Index);
- AssertCapacityUnit(expectItem.Consumed, expectItem.Consumed);
- }
- }
-
- public void AssertBatchWriteRowResponse(
- BatchWriteRowResponse expect, BatchWriteRowResponse actual)
- {
- Assert.AreEqual(expect.TableRespones.Keys, actual.TableRespones.Keys);
-
- foreach (var table in expect.TableRespones)
- {
- Assert.IsTrue(actual.TableRespones.ContainsKey(table.Key));
- var tableExpect = table.Value;
- var tableActual = actual.TableRespones[table.Key];
- AssertOneOperationInBatchWriteRowResponse(tableExpect.Responses, tableActual.Responses);
- }
- }
-
- public void AssertBatchGetRowResponse(
- BatchGetRowResponse expect, BatchGetRowResponse actual)
- {
- Assert.AreEqual(expect.RowDataGroupByTable.Keys, actual.RowDataGroupByTable.Keys);
-
- foreach (var table in expect.RowDataGroupByTable)
- {
- Assert.IsTrue(actual.RowDataGroupByTable.ContainsKey(table.Key));
- var tableExpect = table.Value;
- var tableActual = actual.RowDataGroupByTable[table.Key];
- Assert.AreEqual(tableExpect.Count, tableActual.Count);
- for (int i = 0; i < tableExpect.Count; i++)
- {
- var expectItem = tableExpect[i];
- var actualItem = tableActual[i];
-
- Assert.AreEqual(expectItem.IsOK, actualItem.IsOK);
- Assert.AreEqual(expectItem.ErrorCode, actualItem.ErrorCode);
- Assert.AreEqual(expectItem.ErrorMessage, actualItem.ErrorMessage);
- AssertCapacityUnit(expectItem.Consumed, expectItem.Consumed);
-
- AssertColumns(
- expectItem.PrimaryKey,
- actualItem.PrimaryKey);
- AssertColumns(
- expectItem.Attribute,
- actualItem.Attribute);
- }
- }
- }
-
- public void PutSinglePredefinedRow(int index)
- {
- PutSingleRow(TestTableName,
- GetPredefinedPrimaryKeyWith4PK(index),
- GetPredefinedAttributeWith5PK(index));
- }
-
- public void AssertGetRangeRowWithPredefinedRow(Row row, int index)
- {
- AssertPrimaryKey(GetPredefinedPrimaryKeyWith4PK(index), row.GetPrimaryKey());
- //AssertAttribute(GetPredefinedAttributeWith5PK(index), row.GetColumns());
- }
-
- public void AssertPrimaryKeySchema(PrimaryKeySchema expect, PrimaryKeySchema actual)
- {
- Assert.AreEqual(expect.Count, actual.Count);
-
- for (int i = 0; i < expect.Count; i++)
- {
- Assert.AreEqual(expect[i].Item1, actual[i].Item1);
- Assert.AreEqual(expect[i].Item2, actual[i].Item2);
- }
- }
-
- public void PutPredefinedRows(int count)
- {
- int index = 0;
- while (count > 0)
- {
- var rowChanges = new RowChanges(TestTableName);
-
- for (int i = 0; i < (count > 100 ? 100 : count); i++)
- {
- rowChanges.AddPut(new Condition(RowExistenceExpectation.IGNORE),
- GetPredefinedPrimaryKeyWith4PK(index + i),
- GetPredefinedAttributeWith5PK(index + i)
- );
- }
-
- var request = new BatchWriteRowRequest();
- request.Add(TestTableName, rowChanges);
- OTSClient.BatchWriteRow(request);
-
- count -= 100;
- index += 100;
- }
- }
-
-
- public void SetTestConext(string tableName = null,
- PrimaryKeySchema pkSchema = null,
- CapacityUnit reservedThroughput = null,
- PrimaryKey primaryKey = null,
- AttributeColumns attribute = null,
- UpdateOfAttribute updateOfAttributeForPut = null,
- UpdateOfAttribute updateOfAttributeForDelete = null,
- Condition condition = null,
- GetRangeDirection direction = GetRangeDirection.Forward,
- PrimaryKey startPrimaryKey = null,
- PrimaryKey endPrimaryKey = null,
- HashSet columnsToGet = null,
- int? limit = null,
- CapacityUnit putRowConsumed = null,
- CapacityUnit getRowConsumed = null,
- CapacityUnit updateRowConsumed = null,
- CapacityUnit deleteRowConsumed = null,
- CapacityUnit getRangeConsumed = null,
- Dictionary expectedFailure = null,
- string allFailedMessage = null)
- {
-
- var DefaultPrimaryKeySchema = new PrimaryKeySchema
- {
- { "PK0", ColumnValueType.String },
- { "PK1", ColumnValueType.String },
- { "PK2", ColumnValueType.Integer },
- { "PK3", ColumnValueType.Integer }
- };
-
- var DefaultReservedThroughput = new CapacityUnit(0, 0);
-
- TestContext = new APITestContext
- {
- expectedFailure = expectedFailure,
- allFailedMessage = allFailedMessage,
- tableName = tableName ?? OTSUnitTestBase.TestTableName,
- pkSchema = pkSchema ?? DefaultPrimaryKeySchema,
- reservedThroughput = reservedThroughput ?? DefaultReservedThroughput,
- primaryKey = primaryKey ?? PrimaryKeyWith4Columns,
- attribute = attribute ?? AttributeWith5Columns,
- condition = condition ?? new Condition(RowExistenceExpectation.IGNORE),
- startPrimaryKey = startPrimaryKey ?? MinPrimaryKeyWith4Columns,
- endPrimaryKey = endPrimaryKey ?? MaxPrimaryKeyWith4Columns,
- putRowConsumed = putRowConsumed ?? new CapacityUnit(0, 1),
- getRowConsumed = getRowConsumed ?? new CapacityUnit(1, 0),
- updateRowConsumed = updateRowConsumed ?? GetDefaultCapacityUnit(condition),
- deleteRowConsumed = deleteRowConsumed ?? GetDefaultCapacityUnit(condition),
- getRangeConsumed = getRangeConsumed ?? new CapacityUnit(1, 0),
- columnsToGet = columnsToGet,
- limit = limit,
- direction = direction
- };
-
- if (updateOfAttributeForPut == null)
- {
- updateOfAttributeForPut = new UpdateOfAttribute();
- foreach (var item in TestContext.attribute)
- {
- updateOfAttributeForPut.AddAttributeColumnToPut(item.Key, item.Value);
- }
- }
-
- if (updateOfAttributeForDelete == null)
- {
- updateOfAttributeForDelete = new UpdateOfAttribute();
- foreach (var item in TestContext.attribute)
- {
- updateOfAttributeForDelete.AddAttributeColumnToDelete(item.Key);
- }
- }
-
- TestContext.updateOfAttributeForPut = updateOfAttributeForPut;
- TestContext.updateOfAttributeForDelete = updateOfAttributeForDelete;
- }
-
- ///
- /// Gets the default capacity unit for delete and update operation
- ///
- /// The default capacity unit.
- /// Condition.
- private CapacityUnit GetDefaultCapacityUnit(Condition condition)
- {
- if (condition == null)
- {
- return new CapacityUnit(0, 1);
- }
-
- switch (condition.RowExistenceExpect)
- {
- case RowExistenceExpectation.IGNORE:
- return new CapacityUnit(0, 1);
- case RowExistenceExpectation.EXPECT_EXIST:
- case RowExistenceExpectation.EXPECT_NOT_EXIST:
- return new CapacityUnit(1, 1);
- default:
- throw new Exception("not support default RowExistenceExpect: " + condition.RowExistenceExpect);
- }
- }
-
- public void TestAPIWithParameter(string apiName)
- {
- var tableName = TestContext.tableName;
- var pkSchema = TestContext.pkSchema;
- var reservedThroughput = TestContext.reservedThroughput;
- var primaryKey = TestContext.primaryKey;
- var attribute = TestContext.attribute;
- var condition = TestContext.condition;
- var startPrimaryKey = TestContext.startPrimaryKey;
- var endPrimaryKey = TestContext.endPrimaryKey;
- var putRowConsumed = TestContext.putRowConsumed;
- var getRowConsumed = TestContext.getRowConsumed;
- var updateRowConsumed = TestContext.updateRowConsumed;
- var deleteRowConsumed = TestContext.deleteRowConsumed;
- var getRangeConsumed = TestContext.getRangeConsumed;
- var attributeForPut = TestContext.updateOfAttributeForPut;
- var attributeForDelete = TestContext.updateOfAttributeForDelete;
- var columnsToGet = TestContext.columnsToGet;
- var limit = TestContext.limit;
- var direction = TestContext.direction;
-
- var tableMeta = new TableMeta(tableName, pkSchema);
-
- switch (apiName)
- {
- case "CreateTable":
- var request0 = new CreateTableRequest(tableMeta, reservedThroughput);
- OTSClient.CreateTable(request0);
- return;
-
- case "ListTable":
- var request1 = new ListTableRequest();
- var response1 = OTSClient.ListTable(request1);
- Assert.AreEqual(new List() { tableName }, response1.TableNames);
- return;
-
- case "UpdateTable":
- var request2 = new UpdateTableRequest(tableName)
- {
- ReservedThroughput = reservedThroughput
- };
- var response2 = OTSClient.UpdateTable(request2);
-
- if (reservedThroughput.Read.HasValue && reservedThroughput.Write.HasValue)
- {
- AssertCapacityUnit(
- reservedThroughput,
- response2.ReservedThroughputDetails.CapacityUnit);
- }
-
- Assert.IsTrue(response2.ReservedThroughputDetails.LastDecreaseTime >= 0);
- Assert.IsTrue(response2.ReservedThroughputDetails.LastIncreaseTime >= 0);
- Assert.IsTrue(response2.ReservedThroughputDetails.NumberOfDecreasesToday >= 0);
- return;
-
- case "DeleteTable":
- var request3 = new DeleteTableRequest(tableName);
- OTSClient.DeleteTable(request3);
-
- var request31 = new ListTableRequest();
- var response31 = OTSClient.ListTable(request31);
- Assert.AreEqual(new List() { }, response31.TableNames);
- return;
-
- case "DescribeTable":
- var request4 = new DescribeTableRequest(tableName);
- var response4 = OTSClient.DescribeTable(request4);
- Assert.AreEqual(tableName, response4.TableMeta.TableName);
- AssertPrimaryKeySchema(pkSchema, response4.TableMeta.PrimaryKeySchema);
- AssertCapacityUnit(reservedThroughput, response4.ReservedThroughputDetails.CapacityUnit);
- Assert.IsTrue(response4.ReservedThroughputDetails.LastDecreaseTime >= 0);
- Assert.IsTrue(response4.ReservedThroughputDetails.LastIncreaseTime >= 0);
- Assert.IsTrue(response4.ReservedThroughputDetails.NumberOfDecreasesToday >= 0);
- return;
-
- case "PutRow":
- var request5 = new PutRowRequest(tableName, condition)
- {
- RowPutChange = new RowPutChange(tableName, primaryKey)
- };
-
- foreach (var attr in attributeForPut.AttributeColumnsToPut)
- {
- request5.RowPutChange.AddColumn(new Column(attr.Key, attr.Value));
- }
-
- var response5 = OTSClient.PutRow(request5);
- AssertCapacityUnit(putRowConsumed, response5.ConsumedCapacityUnit);
- return;
-
- case "GetRow":
- var request6 = new GetRowRequest(tableName, primaryKey, columnsToGet);
- var response6 = OTSClient.GetRow(request6);
- AssertPrimaryKey(primaryKey, response6.PrimaryKey, columnsToGet);
- AssertAttribute(attribute, response6.Attribute, columnsToGet);
- AssertCapacityUnit(getRowConsumed, response6.ConsumedCapacityUnit);
- return;
-
- case "DeleteRow":
- var request7 = new DeleteRowRequest(tableName, condition, primaryKey);
- var response7 = OTSClient.DeleteRow(request7);
- AssertCapacityUnit(deleteRowConsumed, response7.ConsumedCapacityUnit);
-
- var request71 = new GetRowRequest(tableName, primaryKey);
- var response71 = OTSClient.GetRow(request71);
- AssertPrimaryKey(new PrimaryKey(), response71.PrimaryKey);
- AssertAttribute(new AttributeColumns(), response71.Attribute);
- return;
-
- case "UpdateRow_Put":
- var request8 = new UpdateRowRequest(tableName, condition, primaryKey, attributeForPut);
- var response8 = OTSClient.UpdateRow(request8);
- AssertCapacityUnit(updateRowConsumed, response8.ConsumedCapacityUnit);
-
- var request81 = new GetRowRequest(tableName, primaryKey);
- var response81 = OTSClient.GetRow(request81);
- AssertPrimaryKey(primaryKey, response81.PrimaryKey);
- AssertAttribute(attribute, response81.Attribute);
- AssertCapacityUnit(getRowConsumed, response81.ConsumedCapacityUnit);
-
- return;
-
- case "UpdateRow_Delete":
- var request9 = new UpdateRowRequest(tableName, condition, primaryKey, attributeForDelete);
- var response9 = OTSClient.UpdateRow(request9);
- AssertCapacityUnit(deleteRowConsumed, response9.ConsumedCapacityUnit);
-
- var request91 = new GetRowRequest(tableName, primaryKey);
- var response91 = OTSClient.GetRow(request91);
- // Don't assert primary key
- AssertAttribute(new AttributeColumns(), response91.Attribute);
- return;
-
- case "BatchGetRow":
- var request11 = new BatchGetRowRequest();
- request11.Add(tableName, new List() { primaryKey }, columnsToGet);
- var response11 = OTSClient.BatchGetRow(request11);
- Assert.AreEqual(1, response11.RowDataGroupByTable.Count);
- Assert.IsTrue(response11.RowDataGroupByTable.ContainsKey(tableName));
- Assert.AreEqual(1, response11.RowDataGroupByTable[tableName].Count);
-
- if (!response11.RowDataGroupByTable[tableName][0].IsOK)
- {
- throw new OTSServerException(apiName, HttpStatusCode.OK,
- response11.RowDataGroupByTable[tableName][0].ErrorCode,
- response11.RowDataGroupByTable[tableName][0].ErrorMessage);
- }
- AssertPrimaryKey(primaryKey, response11.RowDataGroupByTable[tableName][0].PrimaryKey);
- AssertAttribute(attribute, response11.RowDataGroupByTable[tableName][0].Attribute);
- AssertCapacityUnit(getRowConsumed, response11.RowDataGroupByTable[tableName][0].Consumed);
- return;
-
- case "BatchWriteRow_Put":
- var request12 = new BatchWriteRowRequest();
- var rowChanges = new RowChanges(tableName);
- rowChanges.AddPut(condition, primaryKey, attribute);
- request12.Add(tableName, rowChanges);
- var response12 = OTSClient.BatchWriteRow(request12);
- Assert.AreEqual(1, response12.TableRespones.Count);
- Assert.IsTrue(response12.TableRespones.ContainsKey(tableName));
- Assert.AreEqual(1, response12.TableRespones[tableName].Responses.Count);
- if (response12.TableRespones[tableName].Responses[0].IsOK)
- {
- AssertCapacityUnit(putRowConsumed, response12.TableRespones[tableName].Responses[0].Consumed);
- }
- else
- {
- throw new OTSServerException("/BatchWriteRow", HttpStatusCode.OK,
- response12.TableRespones[tableName].Responses[0].ErrorCode,
- response12.TableRespones[tableName].Responses[0].ErrorMessage);
- }
-
-
- var request121 = new GetRowRequest(tableName, primaryKey);
- var response121 = OTSClient.GetRow(request121);
- AssertPrimaryKey(primaryKey, response121.PrimaryKey);
- AssertAttribute(attribute, response121.Attribute);
- AssertCapacityUnit(getRowConsumed, response121.ConsumedCapacityUnit);
- return;
-
- case "BatchWriteRow_Update":
- var request13 = new BatchWriteRowRequest();
- var rowChanges2 = new RowChanges(tableName);
- rowChanges2.AddUpdate(condition, primaryKey, attributeForPut);
- request13.Add(tableName, rowChanges2);
- var response13 = OTSClient.BatchWriteRow(request13);
- Assert.AreEqual(1, response13.TableRespones.Count);
- Assert.IsTrue(response13.TableRespones.ContainsKey(tableName));
- Assert.AreEqual(1, response13.TableRespones[tableName].Responses.Count);
- if (response13.TableRespones[tableName].Responses[0].IsOK)
- {
- AssertCapacityUnit(updateRowConsumed, response13.TableRespones[tableName].Responses[0].Consumed);
- }
- else
- {
- throw new OTSServerException("/BatchWriteRow", HttpStatusCode.OK,
- response13.TableRespones[tableName].Responses[0].ErrorCode,
- response13.TableRespones[tableName].Responses[0].ErrorMessage);
- }
-
- var request131 = new GetRowRequest(tableName, primaryKey);
- var response131 = OTSClient.GetRow(request131);
- AssertPrimaryKey(primaryKey, response131.PrimaryKey);
- AssertAttribute(attribute, response131.Attribute);
- AssertCapacityUnit(getRowConsumed, response131.ConsumedCapacityUnit);
- return;
-
- case "BatchWriteRow_Delete":
- var request14 = new BatchWriteRowRequest();
- var rowChanges3 = new RowChanges(tableName);
- rowChanges3.AddDelete(condition, primaryKey);
- request14.Add(tableName, rowChanges3);
- var response14 = OTSClient.BatchWriteRow(request14);
- Assert.AreEqual(1, response14.TableRespones.Count);
- Assert.IsTrue(response14.TableRespones.ContainsKey(tableName));
- Assert.AreEqual(1, response14.TableRespones[tableName].Responses.Count);
-
- if (response14.TableRespones[tableName].Responses[0].IsOK)
- {
- AssertCapacityUnit(deleteRowConsumed,
- response14.TableRespones[tableName].Responses[0].Consumed);
- }
- else
- {
- throw new OTSServerException("/BatchWriteRow", HttpStatusCode.OK,
- response14.TableRespones[tableName].Responses[0].ErrorCode,
- response14.TableRespones[tableName].Responses[0].ErrorMessage);
- }
- var request141 = new GetRowRequest(tableName, primaryKey);
- var response141 = OTSClient.GetRow(request141);
- AssertPrimaryKey(new PrimaryKey(), response141.PrimaryKey);
- AssertAttribute(new AttributeColumns(), response141.Attribute);
- return;
-
- case "GetRange":
- var request15 = new GetRangeRequest(tableName, direction,
- startPrimaryKey, endPrimaryKey,
- columnsToGet, limit);
- var response15 = OTSClient.GetRange(request15);
- Assert.AreEqual(1, response15.RowDataList.Count);
- Assert.AreEqual(null, response15.NextPrimaryKey);
- AssertCapacityUnit(getRangeConsumed, response15.ConsumedCapacityUnit);
- AssertPrimaryKey(primaryKey, response15.RowDataList[0].GetPrimaryKey(), columnsToGet);
- //AssertAttribute(attribute, response15.RowDataList[0].Attribute, columnsToGet);
- return;
-
- default:
- throw new Exception(String.Format("invalid api name: {0}", apiName));
- }
- }
-
- public void TestSingleAPI(string apiName)
- {
- Console.WriteLine("Testing " + apiName);
- string failedMessage = TestContext.allFailedMessage;
- if (TestContext.expectedFailure != null &&
- TestContext.expectedFailure.ContainsKey(apiName))
- {
- failedMessage = TestContext.expectedFailure[apiName];
- }
-
- if (failedMessage != null)
- {
- try
- {
- TestAPIWithParameter(apiName);
- Assert.Fail();
- }
- catch (OTSServerException exception)
- {
- Assert.AreEqual(failedMessage, exception.ErrorMessage);
- }
- catch (IOException exception)
- {
- Assert.AreEqual(failedMessage, exception.Message);
- }
- catch (Exception exception)
- {
- Console.WriteLine(exception.Message);
- }
- }
- else
- {
- TestAPIWithParameter(apiName);
- }
- }
-
- public void WaitBeforeUpdateTable()
- {
- Thread.Sleep(5000);
- }
-
- public void TestAllAPIWithTableName()
- {
- TestSingleAPI("CreateTable");
- WaitForTableReady();
- TestSingleAPI("DescribeTable");
-
- WaitBeforeUpdateTable();
- TestSingleAPI("UpdateTable");
-
- TestSingleAPI("PutRow");
- TestSingleAPI("GetRow");
- TestSingleAPI("GetRange");
- TestSingleAPI("BatchGetRow");
- TestSingleAPI("DeleteRow");
- TestSingleAPI("UpdateRow_Put");
- TestSingleAPI("UpdateRow_Delete");
- TestSingleAPI("DeleteRow");
- TestSingleAPI("BatchWriteRow_Put");
- TestSingleAPI("BatchWriteRow_Delete");
- TestSingleAPI("DeleteRow");
- TestSingleAPI("BatchWriteRow_Update");
-
- TestSingleAPI("DeleteTable");
- }
-
- public void TestAllDataAPI(bool createTable = true, bool deleteTable = true)
- {
- if (createTable)
- {
- TestSingleAPI("CreateTable");
- WaitForTableReady();
- }
-
- TestSingleAPI("PutRow");
- TestSingleAPI("GetRow");
- TestSingleAPI("GetRange");
- TestSingleAPI("BatchGetRow");
- TestSingleAPI("DeleteRow");
- TestSingleAPI("UpdateRow_Put");
- TestSingleAPI("UpdateRow_Delete");
- TestSingleAPI("DeleteRow");
- TestSingleAPI("BatchWriteRow_Put");
- TestSingleAPI("BatchWriteRow_Delete");
- TestSingleAPI("DeleteRow");
- TestSingleAPI("BatchWriteRow_Update");
-
- if (createTable && deleteTable)
- {
- TestSingleAPI("DeleteTable");
- }
- }
-
- public void TestAllDataAPIWithAttribute(bool createTable = true)
- {
- if (createTable)
- {
- TestSingleAPI("CreateTable");
- WaitForTableReady();
- }
- TestSingleAPI("PutRow");
- TestSingleAPI("UpdateRow_Put");
- TestSingleAPI("UpdateRow_Delete");
- TestSingleAPI("BatchWriteRow_Put");
- TestSingleAPI("BatchWriteRow_Update");
- if (createTable)
- {
- TestSingleAPI("DeleteTable");
- }
- }
-
- public void TestAllDataAPIWithColumnValue(bool createTable = true)
- {
- if (createTable)
- {
- TestSingleAPI("CreateTable");
- WaitForTableReady();
- }
- TestSingleAPI("PutRow");
- TestSingleAPI("UpdateRow_Put");
- TestSingleAPI("BatchWriteRow_Put");
- TestSingleAPI("BatchWriteRow_Update");
-
- if (createTable)
- {
- TestSingleAPI("DeleteTable");
- }
- }
-
- public void TestAllDataAPIWithColumnsToGet()
- {
- TestSingleAPI("GetRow");
- TestSingleAPI("GetRange");
- TestSingleAPI("BatchGetRow");
- }
-
- public string MakeSignature(string apiName, Dictionary headers, string accessKeySecret)
- {
- List items = new List();
-
- foreach (var item in headers)
- {
- if (item.Key.StartsWith("x-ots-", StringComparison.Ordinal) && item.Key != "x-ots-signature")
- {
- items.Add(String.Format("{0}:{1}", item.Key, item.Value));
- }
- }
-
- items.Sort();
- var headerString = String.Join("\n", items);
- string signatureString = headerString + "\n" + apiName;
- var hmac = new HMACSHA1(System.Text.Encoding.ASCII.GetBytes(accessKeySecret));
- byte[] hashValue = hmac.ComputeHash(System.Text.Encoding.ASCII.GetBytes(signatureString));
- string signature = System.Convert.ToBase64String(hashValue);
- return signature;
- }
-
- public Dictionary
- MakeResponseHeaders(string apiName, byte[] httpBody,
- string accessKeyID = null,
- string accessKeySecret = null,
- bool hasRequestID = true,
- bool hasContentMd5 = true)
- {
- accessKeyID = accessKeyID ?? TestAccessKeyID;
- accessKeySecret = accessKeySecret ?? TestAccessKeySecret;
- var serverTime = DateTime.UtcNow;
- var headers = new Dictionary();
-
- // response md5
- if (hasContentMd5)
- {
- var md5hash = MD5.Create();
- byte[] hashData = md5hash.ComputeHash(httpBody);
- string contentMD5 = System.Convert.ToBase64String(hashData);
- headers.Add("x-ots-contentmd5", contentMD5);
- }
-
- // request id
- if (hasRequestID)
- {
- headers.Add("x-ots-requestid", "fake-request-id-for-test");
- }
-
- // date
- headers.Add("x-ots-date", Util.OtsUtils.FormatDateTimeStr(serverTime));
-
- // content type
- headers.Add("x-ots-contenttype", "blah");
-
- // authorization
- var signature = MakeSignature(apiName, headers, accessKeySecret);
- headers.Add("Authorization", String.Format("OTS {0}:{1}", accessKeyID, signature));
-
- return headers;
- }
-
- public byte[] MakeErrorPB(string errorCode, string errorMessage)
- {
- var builder = PB.Error.CreateBuilder();
- builder.Code = errorCode;
- builder.Message = errorMessage;
- var message = builder.Build();
- return message.ToByteArray();
- }
-
- public byte[] MakeListTableResponseBody()
- {
- var builder = PB.ListTableResponse.CreateBuilder();
- builder.AddTableNames("table1");
- builder.AddTableNames("table2");
- var message = builder.Build();
- return message.ToByteArray();
- }
-
- public void DeleteTable(string tableName = null)
- {
- if (tableName == null)
- {
- tableName = TestTableName;
- }
-
- var otsClient = OTSClient;
- var deleteTableRequest = new DeleteTableRequest(tableName);
- otsClient.DeleteTable(deleteTableRequest);
- }
-
- public void CreateTable(string tableName = null, PrimaryKeySchema primaryKeySchema = null)
- {
- var otsClient = OTSClient;
-
- if (tableName == null)
- {
- tableName = TestTableName;
- }
-
- if (primaryKeySchema == null)
- {
- primaryKeySchema = new PrimaryKeySchema
- {
- { "PK0", ColumnValueType.String },
- { "PK1", ColumnValueType.Integer }
- };
- }
-
- var reservedThroughput = new CapacityUnit(0, 0);
-
- CreateTestTable(tableName, primaryKeySchema, reservedThroughput);
- }
- }
-}
+/*
+ * Trade secret of Alibaba Group R&D.
+ * Copyright (c) 2015 Alibaba Group R&D.
+ *
+ * All rights reserved. This notice is intended as a precaution against
+ * inadvertent publication and does not imply publication or any waiver
+ * of confidentiality. The year included in the foregoing notice is the
+ * year of creation of the work.
+ *
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Net;
+using System.IO;
+using System.Security.Cryptography;
+using NUnit.Framework;
+using Aliyun.OTS.DataModel;
+using Aliyun.OTS.Response;
+using Aliyun.OTS.Request;
+using PB = com.alicloud.openservices.tablestore.core.protocol;
+using Aliyun.OTS.DataModel.ConditionalUpdate;
+using Aliyun.OTS.DataModel.Search;
+using System.Threading;
+
+namespace Aliyun.OTS.UnitTest
+{
+ class APITestContext
+ {
+ public string tableName;
+ public PrimaryKeySchema pkSchema;
+ public CapacityUnit reservedThroughput;
+ public PrimaryKey primaryKey;
+ public AttributeColumns attribute;
+ public UpdateOfAttribute updateOfAttributeForPut;
+ public UpdateOfAttribute updateOfAttributeForDelete;
+ public Condition condition;
+ public GetRangeDirection direction = GetRangeDirection.Forward;
+ public PrimaryKey startPrimaryKey;
+ public PrimaryKey endPrimaryKey;
+ public HashSet columnsToGet;
+ public int? limit;
+ public CapacityUnit putRowConsumed;
+ public CapacityUnit getRowConsumed;
+ public CapacityUnit updateRowConsumed;
+ public CapacityUnit deleteRowConsumed;
+ public CapacityUnit getRangeConsumed;
+ public Dictionary expectedFailure;
+ public string allFailedMessage;
+ }
+
+ class LogToFileHandler : OTSDefaultLogHandler
+ {
+ public static new void DefaultErrorLogHandler(string message)
+ {
+ var dateString = GetDateTimeString();
+ using (StreamWriter w = File.AppendText("./log.txt"))
+ {
+ w.Write("OTSClient ERROR {0} {1}", dateString, message);
+ }
+ }
+
+ public static new void DefaultDebugLogHandler(string message)
+ {
+ var dateString = GetDateTimeString();
+ using (StreamWriter w = File.AppendText("./log.txt"))
+ {
+ w.Write("OTSClient DEBUG {0} {1}", dateString, message);
+ }
+ }
+ }
+
+ [TestFixture]
+ class OTSUnitTestBase
+ {
+ public string TestEndPoint = Test.Config.Endpoint;
+ public string TestAccessKeyID = Test.Config.AccessKeyId;
+ public string TestAccessKeySecret = Test.Config.AccessKeySecret;
+ public string TestInstanceName = Test.Config.InstanceName;
+ public OTSClient OTSClient;
+
+ // Predefined test data
+ public static string TestTableName = "SearchQueryTest";
+ public static string TestSearchIndexName = "SearchQueryTestIndex";
+ public static PrimaryKey PrimaryKeyWith4Columns;
+ public static PrimaryKey MinPrimaryKeyWith4Columns;
+ public static PrimaryKey MaxPrimaryKeyWith4Columns;
+ public static AttributeColumns AttributeWith5Columns;
+ public static List PrimaryKeyList;
+ public static List AttributeColumnsList;
+
+ public APITestContext TestContext;
+
+ [SetUp]
+ public void Setup()
+ {
+ Thread.Sleep(1000);
+
+ var clientConfig = new OTSClientConfig(
+ TestEndPoint,
+ TestAccessKeyID,
+ TestAccessKeySecret,
+ TestInstanceName
+ );
+
+ Console.WriteLine("Endpoint: {0}", TestEndPoint);
+ Console.WriteLine("TestAccessKeyID: {0}", TestAccessKeyID);
+ Console.WriteLine("TestAccessKeySecret: {0}", TestAccessKeySecret);
+ Console.WriteLine("TestInstanceName: {0}", TestInstanceName);
+ clientConfig.OTSDebugLogHandler = LogToFileHandler.DefaultDebugLogHandler;
+ clientConfig.OTSErrorLogHandler = LogToFileHandler.DefaultErrorLogHandler;
+ OTSClient = new OTSClient(clientConfig);
+ OTSClientTestHelper.Reset();
+
+ // 删除数据表
+ foreach (var tableName in OTSClient.ListTable(new ListTableRequest()).TableNames)
+ {
+ try
+ {
+ ListSearchIndexRequest listSearchIndexRequest = new ListSearchIndexRequest(tableName);
+ ListSearchIndexResponse listSearchIndexResponse = OTSClient.ListSearchIndex(listSearchIndexRequest);
+
+ foreach (SearchIndexInfo indexInfo in listSearchIndexResponse.IndexInfos)
+ {
+ DeleteSearchIndexRequest deleteSearchIndexRequest = new DeleteSearchIndexRequest(tableName, indexInfo.IndexName);
+ OTSClient.DeleteSearchIndex(deleteSearchIndexRequest);
+ }
+
+ Thread.Sleep(1000);
+
+ DeleteTable(tableName);
+ }
+ catch
+ {
+ Console.WriteLine("Delete Index or Table failed!");
+ }
+ }
+
+ PrimaryKeyWith4Columns = new PrimaryKey
+ {
+ { "PK0", new ColumnValue("ABC") },
+ { "PK1", new ColumnValue("DEF") },
+ { "PK2", new ColumnValue(123) },
+ { "PK3", new ColumnValue(456) }
+ };
+
+ MinPrimaryKeyWith4Columns = new PrimaryKey
+ {
+ { "PK0", ColumnValue.INF_MIN },
+ { "PK1", new ColumnValue("DEF") },
+ { "PK2", new ColumnValue(123) },
+ { "PK3", new ColumnValue(456) }
+ };
+
+ MaxPrimaryKeyWith4Columns = new PrimaryKey
+ {
+ { "PK0", ColumnValue.INF_MAX },
+ { "PK1", new ColumnValue("DEF") },
+ { "PK2", new ColumnValue(123) },
+ { "PK3", new ColumnValue(456) }
+ };
+
+ AttributeWith5Columns = new AttributeColumns
+ {
+ { "Col0", new ColumnValue("ABC") },
+ { "Col1", new ColumnValue(123) },
+ { "Col2", new ColumnValue(3.14) },
+ { "Col3", new ColumnValue(true) },
+ { "Col4", new ColumnValue(new byte[] { 0x20, 0x20 }) }
+ };
+
+ PrimaryKeyList = new List();
+ AttributeColumnsList = new List();
+
+
+ for (int i = 0; i < 1000; i++)
+ {
+ PrimaryKeyList.Add(GetPredefinedPrimaryKeyWith4PK(i));
+ AttributeColumnsList.Add(GetPredefinedAttributeWith5PK(i));
+ }
+
+ // 创建数据表
+ Thread.Sleep(2000);
+ var primaryKeySchema = new PrimaryKeySchema
+ {
+ {"pk0" , ColumnValueType.String},
+ {"pk1" , ColumnValueType.Integer}
+ };
+
+ TableMeta tableMeta = new TableMeta(TestTableName, primaryKeySchema);
+
+ tableMeta.DefinedColumnSchema = new DefinedColumnSchema{
+ { "col1" , DefinedColumnType.STRING},
+ { "col2" , DefinedColumnType.STRING},
+ };
+
+ // TableOptions
+ TableOptions tableOptions = new TableOptions();
+ tableOptions.AllowUpdate = false;
+
+ // 创建二级索引
+ IndexMeta indexMeta = new IndexMeta(TestTableName + "index");
+ indexMeta.PrimaryKey = new List() { "col1" };
+ indexMeta.DefinedColumns = new List() { "col2" };
+
+ List indexMetas = new List() { };
+ indexMetas.Add(indexMeta);
+
+ // ִ执行创建表操作
+ CapacityUnit reservedThroughput = new CapacityUnit(0, 0);
+ CreateTableRequest request = new CreateTableRequest(tableMeta, reservedThroughput);
+ request.TableOptions = tableOptions;
+ CreateTableResponse createTableResponse = OTSClient.CreateTable(request);
+ Console.WriteLine("Create table succeed!");
+
+ // 创建多元索引
+ CreateSearchIndexRequest createSearchIndexRequest = new CreateSearchIndexRequest(TestTableName, TestSearchIndexName);
+ List fieldSchemas = new List {
+ new FieldSchema("col1" , FieldType.KEYWORD){
+ index = true,
+ EnableSortAndAgg = true
+ },
+ new FieldSchema("pk1" , FieldType.LONG) { index = true, EnableSortAndAgg = true},
+ new FieldSchema("col2" , FieldType.TEXT) {
+ index = true ,
+ Analyzer=Analyzer.MaxWord
+ },
+ new FieldSchema("DATE_col" , FieldType.DATE){
+ index = true,
+ DateFormats = new List(){
+ "yyyy-MM-dd'T'HH:mm:ss.SSSSSS",
+ "yyyy-MM-dd'T'HH:mm:ss.SSS"
+ }
+ }
+ };
+
+ createSearchIndexRequest.IndexSchame = new IndexSchema()
+ {
+ FieldSchemas = fieldSchemas,
+ IndexSort = new OTS.DataModel.Search.Sort.Sort(
+ new List
+ {
+ new OTS.DataModel.Search.Sort.FieldSort("pk1", OTS.DataModel.Search.Sort.SortOrder.ASC)
+ })
+ };
+
+ CreateSearchIndexResponse createSearchIndexResponse = OTSClient.CreateSearchIndex(createSearchIndexRequest);
+
+ Console.WriteLine("Create Search Index succeed!");
+ }
+
+ public PrimaryKey GetPredefinedPrimaryKeyWith4PK(int index)
+ {
+ var primaryKey = new PrimaryKey
+ {
+ { "PK0", new ColumnValue("ABC" + index) },
+ { "PK1", new ColumnValue("DEF" + index) },
+ { "PK2", new ColumnValue(123 + index) },
+ { "PK3", new ColumnValue(456 + index) }
+ };
+ return primaryKey;
+ }
+
+ public AttributeColumns GetPredefinedAttributeWith5PK(int index)
+ {
+ var attribute = new AttributeColumns
+ {
+ { "Col0", new ColumnValue("ABC" + index) },
+ { "Col1", new ColumnValue(123 + index) },
+ { "Col2", new ColumnValue(3.14 + index) },
+ { "Col3", new ColumnValue(index % 2 == 0) },
+ { "Col4", new ColumnValue(new byte[] { 0x20, 0x20 }) }
+ };
+ return attribute;
+ }
+
+ public static void WaitForTableReady()
+ {
+ Thread.Sleep(2 * 1000);
+ }
+
+ public static void AssertColumns(Dictionary expect, Dictionary actual, HashSet columnsToGet = null)
+ {
+ if (columnsToGet != null && columnsToGet.Count != 0)
+ {
+ var expectReal = new Dictionary();
+
+ foreach (var columnName in columnsToGet)
+ {
+ if (expect.ContainsKey(columnName))
+ {
+ expectReal.Add(columnName, expect[columnName]);
+ }
+ }
+
+ expect = expectReal;
+ }
+
+ if (expect == null && actual == null)
+ {
+ return;
+ }
+
+
+ Assert.IsTrue(expect != null && actual != null, "expect and actual should NOT be null");
+
+ Assert.AreEqual(expect.Count, actual.Count);
+
+ foreach (var expectValue in expect)
+ {
+ Assert.IsTrue(actual.ContainsKey(expectValue.Key));
+ var actualItem = actual[expectValue.Key];
+ var expectItem = expectValue.Value;
+
+ var result = expectItem.CompareTo(actualItem);
+
+ Assert.IsTrue(result == 0, "columnValue Not equal, expect:" + expectItem + ", actual:" + actualItem);
+ }
+ }
+
+ public static void AssertPrimaryKey(PrimaryKey expect, PrimaryKey actual, HashSet columnsToGet = null)
+ {
+ AssertColumns(expect, actual, columnsToGet);
+ }
+
+ public static void AssertAttribute(AttributeColumns expect, AttributeColumns actual, HashSet columnsToGet = null)
+ {
+ AssertColumns(expect, actual, columnsToGet);
+ }
+
+ public static void AssertAttribute(AttributeColumns expect, Column[] actual, HashSet columnsToGet = null)
+ {
+ AssertColumns(expect, AttributeColumns.ParseColumnArray(actual), columnsToGet);
+ }
+
+ public static void AssertOTSServerException(OTSServerException expect, OTSServerException actual)
+ {
+ if (expect.APIName != actual.APIName ||
+ expect.HttpStatusCode != actual.HttpStatusCode ||
+ expect.ErrorCode != actual.ErrorCode ||
+ expect.ErrorMessage != actual.ErrorMessage)
+ {
+
+ throw new AssertionException(String.Format(
+ "OTSServerException Assert Failed. expect: {0} actual {1}",
+ expect.Message, actual.Message
+ ));
+ }
+ }
+
+ public void CreateTestTable(string tableName, PrimaryKeySchema schema, CapacityUnit reservedThroughput, bool waitFlag = true)
+ {
+ var tableMeta = new TableMeta(tableName, schema);
+
+ var tableOptions = new TableOptions
+ {
+ MaxVersions = 10,
+ TimeToLive = -1
+ };
+
+ var request = new CreateTableRequest(tableMeta, reservedThroughput)
+ {
+ TableOptions = tableOptions
+ };
+
+ OTSClient.CreateTable(request);
+
+ if (waitFlag)
+ {
+ WaitForTableReady();
+ }
+ }
+
+ public void CreateTestTableWith2PK()
+ {
+ var schema = new PrimaryKeySchema
+ {
+ { "PK0", ColumnValueType.String },
+ { "PK1", ColumnValueType.Integer }
+ };
+
+ CreateTestTable(TestTableName, schema, new CapacityUnit(0, 0));
+ }
+
+ public void CreateTestTableWith4PK(CapacityUnit reservedThroughput = null, string tableName = null)
+ {
+ if (reservedThroughput == null)
+ {
+ reservedThroughput = new CapacityUnit(0, 0);
+ }
+
+ var schema = new PrimaryKeySchema
+ {
+ { "PK0", ColumnValueType.String },
+ { "PK1", ColumnValueType.String },
+ { "PK2", ColumnValueType.Integer },
+ { "PK3", ColumnValueType.Integer }
+ };
+
+ if (string.IsNullOrEmpty(tableName))
+ {
+ CreateTestTable(TestTableName, schema, reservedThroughput);
+ }
+ else
+ {
+ CreateTestTable(tableName, schema, reservedThroughput);
+ }
+ }
+
+ public static void AssertCapacityUnit(CapacityUnit expect, CapacityUnit actual)
+ {
+ if (expect == null && actual == null)
+ {
+ return;
+ }
+
+ if (expect == null || actual == null)
+ {
+ Assert.Fail();
+ }
+
+ Assert.AreEqual(expect.Read, actual.Read, "CapacityUnit Read not Matched");
+ Assert.AreEqual(expect.Write, actual.Write, "CapacityUnit Write not Matched");
+ }
+
+ ///
+ /// Puts the single row.
+ ///
+ /// Table name.
+ /// Primary key.
+ /// Attributes.
+ public void PutSingleRow(string tableName, PrimaryKey primaryKey, AttributeColumns attributes)
+ {
+ var request = new PutRowRequest(tableName, new Condition(RowExistenceExpectation.IGNORE));
+ request.RowPutChange.PrimaryKey = primaryKey;
+ foreach (var attribute in attributes)
+ {
+ request.RowPutChange.AddColumn(attribute.Key, attribute.Value);
+ }
+
+ OTSClient.PutRow(request);
+ }
+
+ public void CheckSingleRow(string tableName, PrimaryKey primaryKey,
+ AttributeColumns attribute,
+ CapacityUnit expectCapacityUnitConsumed = null,
+ HashSet columnsToGet = null,
+ bool isEmpty = false,
+ IColumnCondition condition = null)
+ {
+ var request = new GetRowRequest(tableName, primaryKey, columnsToGet, condition);
+
+ var response = OTSClient.GetRow(request);
+
+ PrimaryKey primaryKeyToExpect;
+ AttributeColumns attributeToExpect;
+
+ if (isEmpty)
+ {
+ primaryKeyToExpect = new PrimaryKey();
+ attributeToExpect = new AttributeColumns();
+ }
+ else if (columnsToGet == null || columnsToGet.Count == 0)
+ {
+ primaryKeyToExpect = primaryKey;
+ attributeToExpect = attribute;
+ }
+ else
+ {
+ primaryKeyToExpect = primaryKey;
+ attributeToExpect = new AttributeColumns();
+ foreach (var columnName in columnsToGet)
+ {
+ if (attribute.ContainsKey(columnName))
+ {
+ attributeToExpect.Add(columnName, attribute[columnName]);
+ }
+ }
+ }
+
+ AssertColumns(primaryKeyToExpect, response.PrimaryKey);
+ AssertColumns(attributeToExpect, response.Attribute);
+
+ if (expectCapacityUnitConsumed != null)
+ {
+ AssertCapacityUnit(expectCapacityUnitConsumed, response.ConsumedCapacityUnit);
+ }
+ }
+
+ public static BatchWriteRowResponseForOneTable GetNewBatchWriteRowResponseForOneTable()
+ {
+ var item = new BatchWriteRowResponseForOneTable
+ {
+ Responses = new List()
+ };
+
+ return item;
+ }
+
+ private void AssertOneOperationInBatchWriteRowResponse(
+ IList expect, IList actual)
+ {
+ Assert.AreEqual(expect.Count, actual.Count);
+
+ for (int i = 0; i < expect.Count; i++)
+ {
+ var expectItem = expect[i];
+ var actualItem = actual[i];
+
+ Assert.AreEqual(expectItem.IsOK, actualItem.IsOK);
+ Assert.AreEqual(expectItem.ErrorCode, actualItem.ErrorCode);
+ Assert.AreEqual(expectItem.ErrorMessage, actualItem.ErrorMessage);
+ Assert.AreEqual(expectItem.TableName, actualItem.TableName);
+ Assert.AreEqual(expectItem.Index, actualItem.Index);
+ AssertCapacityUnit(expectItem.Consumed, expectItem.Consumed);
+ }
+ }
+
+ public void AssertBatchWriteRowResponse(
+ BatchWriteRowResponse expect, BatchWriteRowResponse actual)
+ {
+ Assert.AreEqual(expect.TableRespones.Keys, actual.TableRespones.Keys);
+
+ foreach (var table in expect.TableRespones)
+ {
+ Assert.IsTrue(actual.TableRespones.ContainsKey(table.Key));
+ var tableExpect = table.Value;
+ var tableActual = actual.TableRespones[table.Key];
+ AssertOneOperationInBatchWriteRowResponse(tableExpect.Responses, tableActual.Responses);
+ }
+ }
+
+ public void AssertBatchGetRowResponse(
+ BatchGetRowResponse expect, BatchGetRowResponse actual)
+ {
+ Assert.AreEqual(expect.RowDataGroupByTable.Keys, actual.RowDataGroupByTable.Keys);
+
+ foreach (var table in expect.RowDataGroupByTable)
+ {
+ Assert.IsTrue(actual.RowDataGroupByTable.ContainsKey(table.Key));
+ var tableExpect = table.Value;
+ var tableActual = actual.RowDataGroupByTable[table.Key];
+ Assert.AreEqual(tableExpect.Count, tableActual.Count);
+ for (int i = 0; i < tableExpect.Count; i++)
+ {
+ var expectItem = tableExpect[i];
+ var actualItem = tableActual[i];
+
+ Assert.AreEqual(expectItem.IsOK, actualItem.IsOK);
+ Assert.AreEqual(expectItem.ErrorCode, actualItem.ErrorCode);
+ Assert.AreEqual(expectItem.ErrorMessage, actualItem.ErrorMessage);
+ AssertCapacityUnit(expectItem.Consumed, expectItem.Consumed);
+
+ AssertColumns(
+ expectItem.PrimaryKey,
+ actualItem.PrimaryKey);
+ AssertColumns(
+ expectItem.Attribute,
+ actualItem.Attribute);
+ }
+ }
+ }
+
+ public void PutSinglePredefinedRow(int index)
+ {
+ PutSingleRow(TestTableName,
+ GetPredefinedPrimaryKeyWith4PK(index),
+ GetPredefinedAttributeWith5PK(index));
+ }
+
+ public void AssertGetRangeRowWithPredefinedRow(Row row, int index)
+ {
+ AssertPrimaryKey(GetPredefinedPrimaryKeyWith4PK(index), row.GetPrimaryKey());
+ //AssertAttribute(GetPredefinedAttributeWith5PK(index), row.GetColumns());
+ }
+
+ public void AssertPrimaryKeySchema(PrimaryKeySchema expect, PrimaryKeySchema actual)
+ {
+ Assert.AreEqual(expect.Count, actual.Count);
+
+ for (int i = 0; i < expect.Count; i++)
+ {
+ Assert.AreEqual(expect[i].Item1, actual[i].Item1);
+ Assert.AreEqual(expect[i].Item2, actual[i].Item2);
+ }
+ }
+
+ public void PutPredefinedRows(int count)
+ {
+ int index = 0;
+ while (count > 0)
+ {
+ var rowChanges = new RowChanges(TestTableName);
+
+ for (int i = 0; i < (count > 100 ? 100 : count); i++)
+ {
+ rowChanges.AddPut(new Condition(RowExistenceExpectation.IGNORE),
+ GetPredefinedPrimaryKeyWith4PK(index + i),
+ GetPredefinedAttributeWith5PK(index + i)
+ );
+ }
+
+ var request = new BatchWriteRowRequest();
+ request.Add(TestTableName, rowChanges);
+ OTSClient.BatchWriteRow(request);
+
+ count -= 100;
+ index += 100;
+ }
+ }
+
+
+ public void SetTestConext(string tableName = null,
+ PrimaryKeySchema pkSchema = null,
+ CapacityUnit reservedThroughput = null,
+ PrimaryKey primaryKey = null,
+ AttributeColumns attribute = null,
+ UpdateOfAttribute updateOfAttributeForPut = null,
+ UpdateOfAttribute updateOfAttributeForDelete = null,
+ Condition condition = null,
+ GetRangeDirection direction = GetRangeDirection.Forward,
+ PrimaryKey startPrimaryKey = null,
+ PrimaryKey endPrimaryKey = null,
+ HashSet columnsToGet = null,
+ int? limit = null,
+ CapacityUnit putRowConsumed = null,
+ CapacityUnit getRowConsumed = null,
+ CapacityUnit updateRowConsumed = null,
+ CapacityUnit deleteRowConsumed = null,
+ CapacityUnit getRangeConsumed = null,
+ Dictionary expectedFailure = null,
+ string allFailedMessage = null)
+ {
+
+ var DefaultPrimaryKeySchema = new PrimaryKeySchema
+ {
+ { "PK0", ColumnValueType.String },
+ { "PK1", ColumnValueType.String },
+ { "PK2", ColumnValueType.Integer },
+ { "PK3", ColumnValueType.Integer }
+ };
+
+ var DefaultReservedThroughput = new CapacityUnit(0, 0);
+
+ TestContext = new APITestContext
+ {
+ expectedFailure = expectedFailure,
+ allFailedMessage = allFailedMessage,
+ tableName = tableName ?? OTSUnitTestBase.TestTableName,
+ pkSchema = pkSchema ?? DefaultPrimaryKeySchema,
+ reservedThroughput = reservedThroughput ?? DefaultReservedThroughput,
+ primaryKey = primaryKey ?? PrimaryKeyWith4Columns,
+ attribute = attribute ?? AttributeWith5Columns,
+ condition = condition ?? new Condition(RowExistenceExpectation.IGNORE),
+ startPrimaryKey = startPrimaryKey ?? MinPrimaryKeyWith4Columns,
+ endPrimaryKey = endPrimaryKey ?? MaxPrimaryKeyWith4Columns,
+ putRowConsumed = putRowConsumed ?? new CapacityUnit(0, 1),
+ getRowConsumed = getRowConsumed ?? new CapacityUnit(1, 0),
+ updateRowConsumed = updateRowConsumed ?? GetDefaultCapacityUnit(condition),
+ deleteRowConsumed = deleteRowConsumed ?? GetDefaultCapacityUnit(condition),
+ getRangeConsumed = getRangeConsumed ?? new CapacityUnit(1, 0),
+ columnsToGet = columnsToGet,
+ limit = limit,
+ direction = direction
+ };
+
+ if (updateOfAttributeForPut == null)
+ {
+ updateOfAttributeForPut = new UpdateOfAttribute();
+ foreach (var item in TestContext.attribute)
+ {
+ updateOfAttributeForPut.AddAttributeColumnToPut(item.Key, item.Value);
+ }
+ }
+
+ if (updateOfAttributeForDelete == null)
+ {
+ updateOfAttributeForDelete = new UpdateOfAttribute();
+ foreach (var item in TestContext.attribute)
+ {
+ updateOfAttributeForDelete.AddAttributeColumnToDelete(item.Key);
+ }
+ }
+
+ TestContext.updateOfAttributeForPut = updateOfAttributeForPut;
+ TestContext.updateOfAttributeForDelete = updateOfAttributeForDelete;
+ }
+
+ ///
+ /// Gets the default capacity unit for delete and update operation
+ ///
+ /// The default capacity unit.
+ /// Condition.
+ private CapacityUnit GetDefaultCapacityUnit(Condition condition)
+ {
+ if (condition == null)
+ {
+ return new CapacityUnit(0, 1);
+ }
+
+ switch (condition.RowExistenceExpect)
+ {
+ case RowExistenceExpectation.IGNORE:
+ return new CapacityUnit(0, 1);
+ case RowExistenceExpectation.EXPECT_EXIST:
+ case RowExistenceExpectation.EXPECT_NOT_EXIST:
+ return new CapacityUnit(1, 1);
+ default:
+ throw new Exception("not support default RowExistenceExpect: " + condition.RowExistenceExpect);
+ }
+ }
+
+ public void TestAPIWithParameter(string apiName)
+ {
+ var tableName = TestContext.tableName;
+ var pkSchema = TestContext.pkSchema;
+ var reservedThroughput = TestContext.reservedThroughput;
+ var primaryKey = TestContext.primaryKey;
+ var attribute = TestContext.attribute;
+ var condition = TestContext.condition;
+ var startPrimaryKey = TestContext.startPrimaryKey;
+ var endPrimaryKey = TestContext.endPrimaryKey;
+ var putRowConsumed = TestContext.putRowConsumed;
+ var getRowConsumed = TestContext.getRowConsumed;
+ var updateRowConsumed = TestContext.updateRowConsumed;
+ var deleteRowConsumed = TestContext.deleteRowConsumed;
+ var getRangeConsumed = TestContext.getRangeConsumed;
+ var attributeForPut = TestContext.updateOfAttributeForPut;
+ var attributeForDelete = TestContext.updateOfAttributeForDelete;
+ var columnsToGet = TestContext.columnsToGet;
+ var limit = TestContext.limit;
+ var direction = TestContext.direction;
+
+ var tableMeta = new TableMeta(tableName, pkSchema);
+
+ switch (apiName)
+ {
+ case "CreateTable":
+ var request0 = new CreateTableRequest(tableMeta, reservedThroughput);
+ OTSClient.CreateTable(request0);
+ return;
+
+ case "ListTable":
+ var request1 = new ListTableRequest();
+ var response1 = OTSClient.ListTable(request1);
+ Assert.AreEqual(new List() { tableName }, response1.TableNames);
+ return;
+
+ case "UpdateTable":
+ var request2 = new UpdateTableRequest(tableName)
+ {
+ ReservedThroughput = reservedThroughput
+ };
+ var response2 = OTSClient.UpdateTable(request2);
+
+ if (reservedThroughput.Read.HasValue && reservedThroughput.Write.HasValue)
+ {
+ AssertCapacityUnit(
+ reservedThroughput,
+ response2.ReservedThroughputDetails.CapacityUnit);
+ }
+
+ Assert.IsTrue(response2.ReservedThroughputDetails.LastDecreaseTime >= 0);
+ Assert.IsTrue(response2.ReservedThroughputDetails.LastIncreaseTime >= 0);
+ Assert.IsTrue(response2.ReservedThroughputDetails.NumberOfDecreasesToday >= 0);
+ return;
+
+ case "DeleteTable":
+ var request3 = new DeleteTableRequest(tableName);
+ OTSClient.DeleteTable(request3);
+
+ var request31 = new ListTableRequest();
+ var response31 = OTSClient.ListTable(request31);
+ Assert.AreEqual(new List() { }, response31.TableNames);
+ return;
+
+ case "DescribeTable":
+ var request4 = new DescribeTableRequest(tableName);
+ var response4 = OTSClient.DescribeTable(request4);
+ Assert.AreEqual(tableName, response4.TableMeta.TableName);
+ AssertPrimaryKeySchema(pkSchema, response4.TableMeta.PrimaryKeySchema);
+ AssertCapacityUnit(reservedThroughput, response4.ReservedThroughputDetails.CapacityUnit);
+ Assert.IsTrue(response4.ReservedThroughputDetails.LastDecreaseTime >= 0);
+ Assert.IsTrue(response4.ReservedThroughputDetails.LastIncreaseTime >= 0);
+ Assert.IsTrue(response4.ReservedThroughputDetails.NumberOfDecreasesToday >= 0);
+ return;
+
+ case "PutRow":
+ var request5 = new PutRowRequest(tableName, condition)
+ {
+ RowPutChange = new RowPutChange(tableName, primaryKey)
+ };
+
+ foreach (var attr in attributeForPut.AttributeColumnsToPut)
+ {
+ request5.RowPutChange.AddColumn(new Column(attr.Key, attr.Value));
+ }
+
+ var response5 = OTSClient.PutRow(request5);
+ AssertCapacityUnit(putRowConsumed, response5.ConsumedCapacityUnit);
+ return;
+
+ case "GetRow":
+ var request6 = new GetRowRequest(tableName, primaryKey, columnsToGet);
+ var response6 = OTSClient.GetRow(request6);
+ AssertPrimaryKey(primaryKey, response6.PrimaryKey, columnsToGet);
+ AssertAttribute(attribute, response6.Attribute, columnsToGet);
+ AssertCapacityUnit(getRowConsumed, response6.ConsumedCapacityUnit);
+ return;
+
+ case "DeleteRow":
+ var request7 = new DeleteRowRequest(tableName, condition, primaryKey);
+ var response7 = OTSClient.DeleteRow(request7);
+ AssertCapacityUnit(deleteRowConsumed, response7.ConsumedCapacityUnit);
+
+ var request71 = new GetRowRequest(tableName, primaryKey);
+ var response71 = OTSClient.GetRow(request71);
+ AssertPrimaryKey(new PrimaryKey(), response71.PrimaryKey);
+ AssertAttribute(new AttributeColumns(), response71.Attribute);
+ return;
+
+ case "UpdateRow_Put":
+ var request8 = new UpdateRowRequest(tableName, condition, primaryKey, attributeForPut);
+ var response8 = OTSClient.UpdateRow(request8);
+ AssertCapacityUnit(updateRowConsumed, response8.ConsumedCapacityUnit);
+
+ var request81 = new GetRowRequest(tableName, primaryKey);
+ var response81 = OTSClient.GetRow(request81);
+ AssertPrimaryKey(primaryKey, response81.PrimaryKey);
+ AssertAttribute(attribute, response81.Attribute);
+ AssertCapacityUnit(getRowConsumed, response81.ConsumedCapacityUnit);
+
+ return;
+
+ case "UpdateRow_Delete":
+ var request9 = new UpdateRowRequest(tableName, condition, primaryKey, attributeForDelete);
+ var response9 = OTSClient.UpdateRow(request9);
+ AssertCapacityUnit(deleteRowConsumed, response9.ConsumedCapacityUnit);
+
+ var request91 = new GetRowRequest(tableName, primaryKey);
+ var response91 = OTSClient.GetRow(request91);
+ // Don't assert primary key
+ AssertAttribute(new AttributeColumns(), response91.Attribute);
+ return;
+
+ case "BatchGetRow":
+ var request11 = new BatchGetRowRequest();
+ request11.Add(tableName, new List() { primaryKey }, columnsToGet);
+ var response11 = OTSClient.BatchGetRow(request11);
+ Assert.AreEqual(1, response11.RowDataGroupByTable.Count);
+ Assert.IsTrue(response11.RowDataGroupByTable.ContainsKey(tableName));
+ Assert.AreEqual(1, response11.RowDataGroupByTable[tableName].Count);
+
+ if (!response11.RowDataGroupByTable[tableName][0].IsOK)
+ {
+ throw new OTSServerException(apiName, HttpStatusCode.OK,
+ response11.RowDataGroupByTable[tableName][0].ErrorCode,
+ response11.RowDataGroupByTable[tableName][0].ErrorMessage);
+ }
+ AssertPrimaryKey(primaryKey, response11.RowDataGroupByTable[tableName][0].PrimaryKey);
+ AssertAttribute(attribute, response11.RowDataGroupByTable[tableName][0].Attribute);
+ AssertCapacityUnit(getRowConsumed, response11.RowDataGroupByTable[tableName][0].Consumed);
+ return;
+
+ case "BatchWriteRow_Put":
+ var request12 = new BatchWriteRowRequest();
+ var rowChanges = new RowChanges(tableName);
+ rowChanges.AddPut(condition, primaryKey, attribute);
+ request12.Add(tableName, rowChanges);
+ var response12 = OTSClient.BatchWriteRow(request12);
+ Assert.AreEqual(1, response12.TableRespones.Count);
+ Assert.IsTrue(response12.TableRespones.ContainsKey(tableName));
+ Assert.AreEqual(1, response12.TableRespones[tableName].Responses.Count);
+ if (response12.TableRespones[tableName].Responses[0].IsOK)
+ {
+ AssertCapacityUnit(putRowConsumed, response12.TableRespones[tableName].Responses[0].Consumed);
+ }
+ else
+ {
+ throw new OTSServerException("/BatchWriteRow", HttpStatusCode.OK,
+ response12.TableRespones[tableName].Responses[0].ErrorCode,
+ response12.TableRespones[tableName].Responses[0].ErrorMessage);
+ }
+
+
+ var request121 = new GetRowRequest(tableName, primaryKey);
+ var response121 = OTSClient.GetRow(request121);
+ AssertPrimaryKey(primaryKey, response121.PrimaryKey);
+ AssertAttribute(attribute, response121.Attribute);
+ AssertCapacityUnit(getRowConsumed, response121.ConsumedCapacityUnit);
+ return;
+
+ case "BatchWriteRow_Update":
+ var request13 = new BatchWriteRowRequest();
+ var rowChanges2 = new RowChanges(tableName);
+ rowChanges2.AddUpdate(condition, primaryKey, attributeForPut);
+ request13.Add(tableName, rowChanges2);
+ var response13 = OTSClient.BatchWriteRow(request13);
+ Assert.AreEqual(1, response13.TableRespones.Count);
+ Assert.IsTrue(response13.TableRespones.ContainsKey(tableName));
+ Assert.AreEqual(1, response13.TableRespones[tableName].Responses.Count);
+ if (response13.TableRespones[tableName].Responses[0].IsOK)
+ {
+ AssertCapacityUnit(updateRowConsumed, response13.TableRespones[tableName].Responses[0].Consumed);
+ }
+ else
+ {
+ throw new OTSServerException("/BatchWriteRow", HttpStatusCode.OK,
+ response13.TableRespones[tableName].Responses[0].ErrorCode,
+ response13.TableRespones[tableName].Responses[0].ErrorMessage);
+ }
+
+ var request131 = new GetRowRequest(tableName, primaryKey);
+ var response131 = OTSClient.GetRow(request131);
+ AssertPrimaryKey(primaryKey, response131.PrimaryKey);
+ AssertAttribute(attribute, response131.Attribute);
+ AssertCapacityUnit(getRowConsumed, response131.ConsumedCapacityUnit);
+ return;
+
+ case "BatchWriteRow_Delete":
+ var request14 = new BatchWriteRowRequest();
+ var rowChanges3 = new RowChanges(tableName);
+ rowChanges3.AddDelete(condition, primaryKey);
+ request14.Add(tableName, rowChanges3);
+ var response14 = OTSClient.BatchWriteRow(request14);
+ Assert.AreEqual(1, response14.TableRespones.Count);
+ Assert.IsTrue(response14.TableRespones.ContainsKey(tableName));
+ Assert.AreEqual(1, response14.TableRespones[tableName].Responses.Count);
+
+ if (response14.TableRespones[tableName].Responses[0].IsOK)
+ {
+ AssertCapacityUnit(deleteRowConsumed,
+ response14.TableRespones[tableName].Responses[0].Consumed);
+ }
+ else
+ {
+ throw new OTSServerException("/BatchWriteRow", HttpStatusCode.OK,
+ response14.TableRespones[tableName].Responses[0].ErrorCode,
+ response14.TableRespones[tableName].Responses[0].ErrorMessage);
+ }
+ var request141 = new GetRowRequest(tableName, primaryKey);
+ var response141 = OTSClient.GetRow(request141);
+ AssertPrimaryKey(new PrimaryKey(), response141.PrimaryKey);
+ AssertAttribute(new AttributeColumns(), response141.Attribute);
+ return;
+
+ case "GetRange":
+ var request15 = new GetRangeRequest(tableName, direction,
+ startPrimaryKey, endPrimaryKey,
+ columnsToGet, limit);
+ var response15 = OTSClient.GetRange(request15);
+ Assert.AreEqual(1, response15.RowDataList.Count);
+ Assert.AreEqual(null, response15.NextPrimaryKey);
+ AssertCapacityUnit(getRangeConsumed, response15.ConsumedCapacityUnit);
+ AssertPrimaryKey(primaryKey, response15.RowDataList[0].GetPrimaryKey(), columnsToGet);
+ //AssertAttribute(attribute, response15.RowDataList[0].Attribute, columnsToGet);
+ return;
+
+ default:
+ throw new Exception(String.Format("invalid api name: {0}", apiName));
+ }
+ }
+
+ public void TestSingleAPI(string apiName)
+ {
+ Console.WriteLine("Testing " + apiName);
+ string failedMessage = TestContext.allFailedMessage;
+ if (TestContext.expectedFailure != null &&
+ TestContext.expectedFailure.ContainsKey(apiName))
+ {
+ failedMessage = TestContext.expectedFailure[apiName];
+ }
+
+ if (failedMessage != null)
+ {
+ try
+ {
+ TestAPIWithParameter(apiName);
+ Assert.Fail();
+ }
+ catch (OTSServerException exception)
+ {
+ Assert.AreEqual(failedMessage, exception.ErrorMessage);
+ }
+ catch (IOException exception)
+ {
+ Assert.AreEqual(failedMessage, exception.Message);
+ }
+ catch (Exception exception)
+ {
+ Console.WriteLine(exception.Message);
+ }
+ }
+ else
+ {
+ TestAPIWithParameter(apiName);
+ }
+ }
+
+ public void WaitBeforeUpdateTable()
+ {
+ Thread.Sleep(5000);
+ }
+
+ public void TestAllAPIWithTableName()
+ {
+ TestSingleAPI("CreateTable");
+ WaitForTableReady();
+ TestSingleAPI("DescribeTable");
+
+ WaitBeforeUpdateTable();
+ TestSingleAPI("UpdateTable");
+
+ TestSingleAPI("PutRow");
+ TestSingleAPI("GetRow");
+ TestSingleAPI("GetRange");
+ TestSingleAPI("BatchGetRow");
+ TestSingleAPI("DeleteRow");
+ TestSingleAPI("UpdateRow_Put");
+ TestSingleAPI("UpdateRow_Delete");
+ TestSingleAPI("DeleteRow");
+ TestSingleAPI("BatchWriteRow_Put");
+ TestSingleAPI("BatchWriteRow_Delete");
+ TestSingleAPI("DeleteRow");
+ TestSingleAPI("BatchWriteRow_Update");
+
+ TestSingleAPI("DeleteTable");
+ }
+
+ public void TestAllDataAPI(bool createTable = true, bool deleteTable = true)
+ {
+ if (createTable)
+ {
+ TestSingleAPI("CreateTable");
+ WaitForTableReady();
+ }
+
+ TestSingleAPI("PutRow");
+ TestSingleAPI("GetRow");
+ TestSingleAPI("GetRange");
+ TestSingleAPI("BatchGetRow");
+ TestSingleAPI("DeleteRow");
+ TestSingleAPI("UpdateRow_Put");
+ TestSingleAPI("UpdateRow_Delete");
+ TestSingleAPI("DeleteRow");
+ TestSingleAPI("BatchWriteRow_Put");
+ TestSingleAPI("BatchWriteRow_Delete");
+ TestSingleAPI("DeleteRow");
+ TestSingleAPI("BatchWriteRow_Update");
+
+ if (createTable && deleteTable)
+ {
+ TestSingleAPI("DeleteTable");
+ }
+ }
+
+ public void TestAllDataAPIWithAttribute(bool createTable = true)
+ {
+ if (createTable)
+ {
+ TestSingleAPI("CreateTable");
+ WaitForTableReady();
+ }
+ TestSingleAPI("PutRow");
+ TestSingleAPI("UpdateRow_Put");
+ TestSingleAPI("UpdateRow_Delete");
+ TestSingleAPI("BatchWriteRow_Put");
+ TestSingleAPI("BatchWriteRow_Update");
+ if (createTable)
+ {
+ TestSingleAPI("DeleteTable");
+ }
+ }
+
+ public void TestAllDataAPIWithColumnValue(bool createTable = true)
+ {
+ if (createTable)
+ {
+ TestSingleAPI("CreateTable");
+ WaitForTableReady();
+ }
+ TestSingleAPI("PutRow");
+ TestSingleAPI("UpdateRow_Put");
+ TestSingleAPI("BatchWriteRow_Put");
+ TestSingleAPI("BatchWriteRow_Update");
+
+ if (createTable)
+ {
+ TestSingleAPI("DeleteTable");
+ }
+ }
+
+ public void TestAllDataAPIWithColumnsToGet()
+ {
+ TestSingleAPI("GetRow");
+ TestSingleAPI("GetRange");
+ TestSingleAPI("BatchGetRow");
+ }
+
+ public string MakeSignature(string apiName, Dictionary headers, string accessKeySecret)
+ {
+ List items = new List();
+
+ foreach (var item in headers)
+ {
+ if (item.Key.StartsWith("x-ots-", StringComparison.Ordinal) && item.Key != "x-ots-signature")
+ {
+ items.Add(String.Format("{0}:{1}", item.Key, item.Value));
+ }
+ }
+
+ items.Sort();
+ var headerString = String.Join("\n", items);
+ string signatureString = headerString + "\n" + apiName;
+ var hmac = new HMACSHA1(System.Text.Encoding.ASCII.GetBytes(accessKeySecret));
+ byte[] hashValue = hmac.ComputeHash(System.Text.Encoding.ASCII.GetBytes(signatureString));
+ string signature = System.Convert.ToBase64String(hashValue);
+ return signature;
+ }
+
+ public Dictionary
+ MakeResponseHeaders(string apiName, byte[] httpBody,
+ string accessKeyID = null,
+ string accessKeySecret = null,
+ bool hasRequestID = true,
+ bool hasContentMd5 = true)
+ {
+ accessKeyID = accessKeyID ?? TestAccessKeyID;
+ accessKeySecret = accessKeySecret ?? TestAccessKeySecret;
+ var serverTime = DateTime.UtcNow;
+ var headers = new Dictionary();
+
+ // response md5
+ if (hasContentMd5)
+ {
+ var md5hash = MD5.Create();
+ byte[] hashData = md5hash.ComputeHash(httpBody);
+ string contentMD5 = System.Convert.ToBase64String(hashData);
+ headers.Add("x-ots-contentmd5", contentMD5);
+ }
+
+ // request id
+ if (hasRequestID)
+ {
+ headers.Add("x-ots-requestid", "fake-request-id-for-test");
+ }
+
+ // date
+ headers.Add("x-ots-date", Util.OtsUtils.FormatDateTimeStr(serverTime));
+
+ // content type
+ headers.Add("x-ots-contenttype", "blah");
+
+ // authorization
+ var signature = MakeSignature(apiName, headers, accessKeySecret);
+ headers.Add("Authorization", String.Format("OTS {0}:{1}", accessKeyID, signature));
+
+ return headers;
+ }
+
+ public byte[] MakeErrorPB(string errorCode, string errorMessage)
+ {
+ var builder = PB.Error.CreateBuilder();
+ builder.Code = errorCode;
+ builder.Message = errorMessage;
+ var message = builder.Build();
+ return message.ToByteArray();
+ }
+
+ public byte[] MakeListTableResponseBody()
+ {
+ var builder = PB.ListTableResponse.CreateBuilder();
+ builder.AddTableNames("table1");
+ builder.AddTableNames("table2");
+ var message = builder.Build();
+ return message.ToByteArray();
+ }
+
+ public void DeleteTable(string tableName = null)
+ {
+ if (tableName == null)
+ {
+ tableName = TestTableName;
+ }
+
+ var otsClient = OTSClient;
+ var deleteTableRequest = new DeleteTableRequest(tableName);
+ otsClient.DeleteTable(deleteTableRequest);
+ }
+
+ public void CreateTable(string tableName = null, PrimaryKeySchema primaryKeySchema = null)
+ {
+ var otsClient = OTSClient;
+
+ if (tableName == null)
+ {
+ tableName = TestTableName;
+ }
+
+ if (primaryKeySchema == null)
+ {
+ primaryKeySchema = new PrimaryKeySchema
+ {
+ { "PK0", ColumnValueType.String },
+ { "PK1", ColumnValueType.Integer }
+ };
+ }
+
+ var reservedThroughput = new CapacityUnit(0, 0);
+
+ CreateTestTable(tableName, primaryKeySchema, reservedThroughput);
+ }
+ }
+}
diff --git a/test/UnitTest/SearchTest.cs b/test/UnitTest/SearchTest.cs
index e16e4f2..4536efe 100644
--- a/test/UnitTest/SearchTest.cs
+++ b/test/UnitTest/SearchTest.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
using System.Collections.Generic;
using Aliyun.OTS.DataModel;
using Aliyun.OTS.DataModel.Search;
@@ -447,11 +447,11 @@ public void TestGroupByGeoDistance()
GroupByName = groupByName,
FieldName = Geo_Column,
Origin = new GeoPoint(0, 0),
- Ranges = new List
+ Ranges = new List
{
- new Range(double.MinValue , 1000.0),
- new Range(1000.0, 5000.0),
- new Range(5000.0, double.MaxValue)
+ new OTS.DataModel.Search.GroupBy.Range(double.MinValue , 1000.0),
+ new OTS.DataModel.Search.GroupBy.Range(1000.0, 5000.0),
+ new OTS.DataModel.Search.GroupBy.Range(5000.0, double.MaxValue)
}
};
@@ -501,12 +501,12 @@ public void TestGroupByRange()
GroupByRange groupByRange = new GroupByRange();
groupByRange.FieldName = Col2_Double;
groupByRange.GroupByName = groupByName;
- groupByRange.Ranges = new List
+ groupByRange.Ranges = new List
{
- new Range(double.MinValue, 5.0),
- new Range(5.0, 50.0),
- new Range(50.0, 100.0),
- new Range(100.0, double.MaxValue)
+ new OTS.DataModel.Search.GroupBy.Range(double.MinValue, 5.0),
+ new OTS.DataModel.Search.GroupBy.Range(5.0, 50.0),
+ new OTS.DataModel.Search.GroupBy.Range(50.0, 100.0),
+ new OTS.DataModel.Search.GroupBy.Range(100.0, double.MaxValue)
};
GroupByResults results = TestGroupByBase(groupByRange);
diff --git a/test/aliyun-tablestore-sdk-netcore-test.csproj b/test/aliyun-tablestore-sdk-netcore-test.csproj
new file mode 100644
index 0000000..cd2b15e
--- /dev/null
+++ b/test/aliyun-tablestore-sdk-netcore-test.csproj
@@ -0,0 +1,76 @@
+
+
+ netcoreapp3.1
+ Aliyun.TableStore.Test
+ False
+ False
+ false
+ false
+ false
+ false
+ false
+ false
+ false
+ false
+ Aliyun.TableStore.NetCore.Test
+ true
+
+
+ Library
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/test/aliyun-tablestore-sdk-test.csproj b/test/aliyun-tablestore-sdk-test.csproj
index 358fe75..ca52418 100644
--- a/test/aliyun-tablestore-sdk-test.csproj
+++ b/test/aliyun-tablestore-sdk-test.csproj
@@ -1,19 +1,30 @@
-
-
+
+
Debug
AnyCPU
- {F30E0874-399A-4FBD-B72B-74EE36B31AF6}
+ {9D7540C1-72D3-496E-AB6E-29534A06C037}
Library
Properties
- Aliyun.OTS.Test
- Aliyun.TableStore.Test
+ Aliyun.Tablestore.Net40.Test
+ Aliyun.Tablestore.Net40.Test
+ False
+ False
+ false
+ false
+ false
+ false
+ false
+ false
+ false
+ v4.0
512
-
- 8.0.30703
- 2.0
+ true
+ true
+ false
+ false
@@ -25,9 +36,6 @@
DEBUG;TRACE
prompt
4
- MixedMinimumRules.ruleset
- true
- x86
pdbonly
@@ -36,24 +44,24 @@
TRACE
prompt
4
- x86
- true
-
+
+ ..\packages\Bosima.Google.ProtocolBuffers.1.0.1\lib\net40\Google.ProtocolBuffers.dll
+
..\packages\Newtonsoft.Json.13.0.1\lib\net40\Newtonsoft.Json.dll
-
- ..\packages\NUnit.3.10.1\lib\net40\nunit.framework.dll
+
+ ..\packages\NUnit.3.13.3\lib\net40\nunit.framework.dll
-
- ..\packages\Google.ProtocolBuffers.2.4.1.555\lib\net40\Google.ProtocolBuffers.dll
-
-
- ..\packages\Google.ProtocolBuffers.2.4.1.555\lib\net40\Google.ProtocolBuffers.Serialization.dll
-
+
+
+
+
+
+
@@ -92,27 +100,20 @@
-
-
-
- {AB5EFCA2-53A9-42B5-861E-3FD6F865036B}
+ {ab5efca2-53a9-42b5-861e-3fd6f865036b}
aliyun-tablestore-sdk
+
+
+
这台计算机上缺少此项目引用的 NuGet 程序包。使用“NuGet 程序包还原”可下载这些程序包。有关更多信息,请参见 http://go.microsoft.com/fwlink/?LinkID=322105。缺少的文件是 {0}。
-
-
-
\ No newline at end of file
diff --git a/test/packages.config b/test/packages.config
index cc1b6ab..00faf5c 100644
--- a/test/packages.config
+++ b/test/packages.config
@@ -1,7 +1,6 @@
-
-
+
-
+
\ No newline at end of file