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