Skip to content

Commit bccab20

Browse files
kaibocailucyzhang929shreyas-gopalakrishna
authored
Add end to end test for SQL Bindings (#742)
* add sql e2e test * remove sql trigger test * check sql input result * update sql java library version to 2.1.0 * remove sql trigger function * remove GetProducts2 * Updating library version. Fixes merge conflict --------- Co-authored-by: Lucy Zhang <[email protected]> Co-authored-by: Shreyas Gopalakrishna <[email protected]> Co-authored-by: Shreyas Gopalakrishna <[email protected]>
1 parent a298511 commit bccab20

File tree

8 files changed

+148
-6
lines changed

8 files changed

+148
-6
lines changed

azure-pipelines-e2e-integration-tests.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,7 @@ jobs:
149149
JAVA_HOME: $(JavaHome)
150150
AzureWebJobsStorage: $(AzureWebJobsStorage)
151151
AzureWebJobsCosmosDBConnectionString: $(AzureWebJobsCosmosDBConnectionString)
152+
AzureWebJobsSqlConnectionString: $(AzureWebJobsSqlConnectionString)
152153
AzureWebJobsServiceBus: $(AzureWebJobsServiceBus)
153154
AzureWebJobsEventHubSender_2: $(AzureWebJobsEventHubSender_2)
154155
AzureWebJobsEventHubReceiver: $(AzureWebJobsEventHubReceiver)

azure-pipelines.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,7 @@ jobs:
211211
JAVA_HOME: $(JavaHome)
212212
AzureWebJobsStorage: $(AzureWebJobsStorage)
213213
AzureWebJobsCosmosDBConnectionString: $(AzureWebJobsCosmosDBConnectionString)
214+
AzureWebJobsSqlConnectionString: $(AzureWebJobsSqlConnectionString)
214215
AzureWebJobsServiceBus: $(AzureWebJobsServiceBus)
215216
AzureWebJobsEventHubReceiver: $(AzureWebJobsEventHubReceiver)
216217
AzureWebJobsEventHubSender_2: $(AzureWebJobsEventHubSender_2)

endtoendtests/Azure.Functions.Java.Tests.E2E/Azure.Functions.Java.Tests.E2E/Constants.cs

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ namespace Azure.Functions.Java.Tests.E2E
88
public static class Constants
99
{
1010
public static string FunctionsHostUrl = Environment.GetEnvironmentVariable("FunctionAppUrl") ?? "http://localhost:7071";
11-
public static string StorageConnectionStringSetting = Environment.GetEnvironmentVariable("AzureWebJobsStorage");
11+
public static string StorageConnectionStringSetting = Environment.GetEnvironmentVariable("AzureWebJobsStorage");
1212

1313

1414
//Queue tests
@@ -87,11 +87,14 @@ public static class Constants
8787
public static string ServiceBusConnectionStringSetting = Environment.GetEnvironmentVariable("AzureWebJobsServiceBus");
8888

8989
// Xunit Fixtures and Collections
90-
public const string FunctionAppCollectionName = "FunctionAppCollection";
91-
92-
// Application Insights
93-
public static string ApplicationInsightAPIKey = Environment.GetEnvironmentVariable("ApplicationInsightAPIKey");
94-
public static string ApplicationInsightAPPID = Environment.GetEnvironmentVariable("ApplicationInsightAPPID");
90+
public const string FunctionAppCollectionName = "FunctionAppCollection";
91+
92+
// Application Insights
93+
public static string ApplicationInsightAPIKey = Environment.GetEnvironmentVariable("ApplicationInsightAPIKey");
94+
public static string ApplicationInsightAPPID = Environment.GetEnvironmentVariable("ApplicationInsightAPPID");
9595
public static string ApplicationInsightAgentVersion = Environment.GetEnvironmentVariable("ApplicationInsightAgentVersion");
96+
97+
// SQL Binding tests
98+
public static string SqlConnectionStringSetting = Environment.GetEnvironmentVariable("AzureWebJobsSqlConnectionString");
9699
}
97100
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
// Copyright (c) .NET Foundation. All rights reserved.
2+
// Licensed under the MIT License. See License.txt in the project root for license information.
3+
4+
using Newtonsoft.Json;
5+
using System;
6+
using System.Collections.Generic;
7+
using System.Net;
8+
using System.Threading;
9+
using System.Threading.Tasks;
10+
using Xunit;
11+
12+
namespace Azure.Functions.Java.Tests.E2E
13+
{
14+
[Collection(Constants.FunctionAppCollectionName)]
15+
public class SqlEndToEndTests
16+
{
17+
private readonly FunctionAppFixture _fixture;
18+
19+
public SqlEndToEndTests(FunctionAppFixture fixture)
20+
{
21+
this._fixture = fixture;
22+
}
23+
24+
[Fact]
25+
public async Task SqlInput_Output_Succeeds()
26+
{
27+
TimeSpan t = DateTime.UtcNow - new DateTime(1970, 1, 1);
28+
int id = (int) t.TotalSeconds;
29+
var product = new Dictionary<string, object>()
30+
{
31+
{ "ProductId", id },
32+
{ "Name", "test" },
33+
{ "Cost", 100 }
34+
};
35+
36+
var productString = JsonConvert.SerializeObject(product);
37+
// Insert row into Products table using SqlOutput
38+
Assert.True(await Utilities.InvokeHttpTriggerPost("AddProduct", productString, HttpStatusCode.OK));
39+
40+
// Read row from Products table using SqlInput
41+
Assert.True(await Utilities.InvokeHttpTrigger("GetProducts", "/" + id.ToString(), HttpStatusCode.OK, productString));
42+
}
43+
}
44+
}

endtoendtests/Azure.Functions.Java.Tests.E2E/Azure.Functions.Java.Tests.E2E/Utilities.cs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,30 @@ public static async Task<bool> InvokeHttpTrigger(string functionName, string que
6464
}
6565
}
6666

67+
public static async Task<bool> InvokeHttpTriggerPost(string functionName, string bodyString, HttpStatusCode expectedStatusCode)
68+
{
69+
string uri = $"{Constants.FunctionsHostUrl}/api/{functionName}";
70+
using (var request = new HttpRequestMessage(HttpMethod.Post, uri))
71+
{
72+
request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("text/plain"));
73+
request.Content = new StringContent(
74+
bodyString,
75+
Encoding.UTF8,
76+
"application/json"
77+
);
78+
var response = await httpClient.SendAsync(request);
79+
80+
Console.WriteLine(
81+
$"InvokeHttpTrigger: {functionName} : {response.StatusCode} : {response.ReasonPhrase}");
82+
if (expectedStatusCode != response.StatusCode)
83+
{
84+
return false;
85+
}
86+
87+
return true;
88+
}
89+
}
90+
6791
public static async Task<bool> InvokeEventGridTrigger(string functionName, JObject jsonContent, HttpStatusCode expectedStatusCode=HttpStatusCode.Accepted)
6892
{
6993
string uri = $"{Constants.FunctionsHostUrl}/runtime/webhooks/eventgrid?functionName={functionName}";

endtoendtests/local.settings.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
"AzureWebJobsCosmosDBConnectionString":"",
1818
"AzureWebJobsEventGridOutputBindingTopicUriString": "",
1919
"AzureWebJobsEventGridOutputBindingTopicKeyString": "",
20+
"AzureWebJobsSqlConnectionString": "",
2021
"FUNCTIONS_WORKER_RUNTIME": "java"
2122
}
2223
}

endtoendtests/pom.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
<java.version>1.8</java.version>
2424
<azure.functions.maven.plugin.version>1.18.0</azure.functions.maven.plugin.version>
2525
<azure.functions.java.library.version>3.1.0</azure.functions.java.library.version>
26+
<azure.functions.java.library.sql.version>2.1.0</azure.functions.java.library.sql.version>
2627
<durabletask.azure.functions>1.0.0-beta.1</durabletask.azure.functions>
2728
<functionAppName>azure-functions-java-endtoendtests</functionAppName>
2829
<functionAppRegion>westus</functionAppRegion>
@@ -64,6 +65,11 @@
6465
<artifactId>azure-functions-java-library</artifactId>
6566
<version>${azure.functions.java.library.version}</version>
6667
</dependency>
68+
<dependency>
69+
<groupId>com.microsoft.azure.functions</groupId>
70+
<artifactId>azure-functions-java-library-sql</artifactId>
71+
<version>${azure.functions.java.library.sql.version}</version>
72+
</dependency>
6773
<dependency>
6874
<groupId>com.microsoft</groupId>
6975
<artifactId>durabletask-azure-functions</artifactId>
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
package com.microsoft.azure.functions.endtoend;
2+
3+
import com.microsoft.azure.functions.annotation.*;
4+
import com.google.gson.Gson;
5+
import com.microsoft.azure.functions.*;
6+
import com.microsoft.azure.functions.HttpMethod;
7+
import com.microsoft.azure.functions.sql.annotation.CommandType;
8+
import com.microsoft.azure.functions.sql.annotation.SQLInput;
9+
import com.microsoft.azure.functions.sql.annotation.SQLOutput;
10+
import com.microsoft.azure.functions.sql.annotation.SQLTrigger;
11+
12+
import java.io.IOException;
13+
import java.lang.reflect.Array;
14+
import java.util.*;
15+
16+
/**
17+
* Azure Functions with Azure SQL DB.
18+
*/
19+
public class SqlTriggerTests {
20+
21+
@FunctionName("GetProducts")
22+
public HttpResponseMessage GetProducts(@HttpTrigger(name = "req", methods = { HttpMethod.GET,
23+
HttpMethod.POST }, route = "getproducts/{productid}", authLevel = AuthorizationLevel.ANONYMOUS)
24+
HttpRequestMessage<Optional<String>> request,
25+
@SQLInput(name = "products", commandText = "SELECT TOP 1 * FROM Products WHERE ProductId = @ProductId",
26+
commandType = CommandType.Text, parameters = "@ProductId={productid}",
27+
connectionStringSetting = "AzureWebJobsSqlConnectionString") Product[] products,
28+
final ExecutionContext context) {
29+
30+
context.getLogger().info("Java HTTP trigger processed a request.");
31+
32+
if (products.length != 0) {
33+
return request.createResponseBuilder(HttpStatus.OK).body(products[0].toString()).build();
34+
} else {
35+
return request.createResponseBuilder(HttpStatus.INTERNAL_SERVER_ERROR)
36+
.body("Did not find expected product in table Products").build();
37+
}
38+
}
39+
40+
@FunctionName("AddProduct")
41+
public HttpResponseMessage AddProduct(@HttpTrigger(name = "req", methods = { HttpMethod.GET,
42+
HttpMethod.POST }, authLevel = AuthorizationLevel.ANONYMOUS) HttpRequestMessage<Optional<String>> request,
43+
@SQLOutput(name = "product", commandText = "Products", connectionStringSetting = "AzureWebJobsSqlConnectionString") OutputBinding<Product> product,
44+
final ExecutionContext context) {
45+
context.getLogger().info("Java HTTP trigger processed a request.");
46+
47+
String json = request.getBody().get();
48+
product.setValue(new Gson().fromJson(json, Product.class));
49+
50+
return request.createResponseBuilder(HttpStatus.OK).body(product).build();
51+
}
52+
53+
public class Product {
54+
public int ProductId;
55+
public String Name;
56+
public int Cost;
57+
58+
public String toString() {
59+
return "{\"ProductId\":" + ProductId + ",\"Name\":\"" + Name + "\",\"Cost\":" + Cost + "}";
60+
}
61+
}
62+
}

0 commit comments

Comments
 (0)