I’ve been a Java developer for a long time, and when I started learning Python I constantly found myself wondering, “Hm, how do I do (such and such) in Python?”
The web is great for stuff like that, of course, but sometimes a video that showed me JUST the thing I wanted to see would have been great.
If you’re interested in the goings-on of the Java language, be sure to check out my new Web Series on IBM Developer called A Strong Cup of Java.
The show will focus on interesting topics in the world of Java.
Episode One is about Jakarta EE, where I talk about what Jakarta EE is, and how it got its name (whatever happened to J2EE?).
Episode Two covers the launch of Jakarta EE 8 (the first release of enterprise Java since Java EE 8 in 2017) that happened on September 10, 2019 in an all-day live stream called JakartaOne.
In the coming weeks, there will be eight more episodes published (I have a 10 episode committment from IBM for the series). With your support there may be more, so please watch!
Click here for the show notes page at IBM Developer.
If you have ideas for topics, please let me know. Thanks for reading!
Before diving into the meat of this, let me show you the class under test. It’s called Echo, and it’s very simple (so as not to get in the way of the lesson):
public class Echo {
public String echo(String stringToEcho) {
return stringToEcho;
}
public Integer echo(Integer intToEcho) {
return intToEcho;
}
}
The class is pretty simple: its contract stipulates that it echoes whatever is passed, unchanged.
In true Test-Driven Development (TDD) style, you’ll write the implementation after you write the unit tests.
@Disabled
@Test
@Disabled
@DisplayName("A disabled test")
void testNotRun() {
// This method will not run
}
Use this annotation to tell the JUnit platform not to run this test method. Notice that the method is annotated with the @Test annotation. Normally, JUnit would execute this method at the appropriate point in the test lifecycle, but annotating the method with @Disabled tells JUnit not to run it.
Why not just remove the @Test annotation? It might be good for documentation purposes to leave it annotated with @Test so you know it was a test method, or maybe you just want to temporarily disable the method.
@Nested
This is a super cool new feature of JUnit 5 that allows you to create nested (inner) classes that keep groups of tests together in the same main test class, but separate from the other test methods in that class.
In the case of the Echo class, both methods are called echo, so you need some way of distinguishing which echo overload you’re testing. You could do something like this:
@Test
public void testEcho_String() {
.
.
}
@Test
public void testEcho_Integer() {
.
.
}
And that would work just fine. But JUnit 5 and the Jupiter API give you the @Nested annotation. So let’s use it!
@Nested
public class StringEchoTest {
@Test
public void testEcho() {
classUnderTest = new Echo();
String expectedString = "This is a test";
assertAll("String version of echo() method",
// equals() should match,
/// but that is not good enough
() -> assertEquals(expectedString,
classUnderTest.echo(expectedString)),
// hash codes should match,
/// but still not quite good enough
() -> assertEquals(expectedString.hashCode(),
classUnderTest.echo(expectedString).hashCode()),
// This should do the trick
() -> assertEquals(
System.identityHashCode(expectedString),
System.identityHashCode(
classUnderTest.echo(expectedString))));
}
}
@Nested
public class IntegerEchoTest {
@Test
public void testEcho() {
classUnderTest = new Echo();
Integer expectedInteger = Integer.valueOf(238);
assertAll("String version of echo() method",
() -> assertEquals(expectedInteger,
classUnderTest.echo(expectedInteger)),
() -> assertEquals(expectedInteger.hashCode(),
classUnderTest.echo(expectedInteger).hashCode()),
() -> assertEquals(
System.identityHashCode(expectedInteger),
System.identityHashCode(
classUnderTest.echo(expectedInteger))));
}
}
Video
In the video below, I’ll go over these annotations in detail, and you can watch me explain the code as I write it.
Conclusion
In this article, I showed you some of the annotations from the JUnit Jupiter API you’re most likely to use. But there is a LOT more to JUnit than the Annotations.
Be sure to follow along with this series here on my blog, and the accompanying videos on my YouTube channel.
To learn more about the annotations provided by the JUnit Jupiter API visit the JUnit 5 User’s Guide.
Check out my IBM developerWorks JUnit 5 Tutorial Series:
Hey everybody! In this post, I’d like to talk about Container-centric infrastructure with Kubernetes. This is Part 5 of a series of posts on using installing and using Kubernetes.
In this post I’ll show you two ways to manage your Kubernetes applications:
kubectl
Kubernetes Web UI Dashboard
The kubectl command
When Kubernetes starts a pod it’s isolated in its own network. So how do we interact with the application?
One way is through a proxy, which you can start in a separate terminal window. Start a new Terminal window and execute the kubectl proxy command.
kubectl proxy
By default the proxy uses port 8001, but you can specify a different port using the --port option.
kubectl proxy --port=8080
This starts the proxy using port 8080. Now you can connect to the cluster through port 8080 on your computer.
I’ve written a script to get the pod name and use it to access the application through the cluster’s REST interface. The script is called test-k8sdemo.sh and takes the port as an argument.
./test-k8sdemo.sh 8080
And there you see the output.
Now that we have an app up and running, let’s talk about how to manage it. You can use the kubectl command to get information about pods, deployments, and so on.
For example, you can show a listing of the deployments:
kubectl get deployments
Or of the pods:
kubectl get pods
You can even get detailed information about the pods:
kubectl describe pods
This produces a lot of output, but it’s valuable (if somewhat verbose) information.
Kubernetes Web UI Dashboard
Now I love the command line as much as anybody, but did you know that Kubernetes has a Web-based UI dashboard?
By default the Dashboard is not deployed. From the documentation, you can copy the command to create the deployment through the kubectl command:
Paste the above command into the console to deploy it.
Make sure the proxy is running (I showed you how to do this in Part 4). Start the proxy in a separate Terminal window:
kubectl proxy --port=8001
Once the Dashboard is deployed you can access it from http://localhost:8001/ui.
You can see the same basic information as from the various kubectl commands, but in a UI. Here’s an example of what I see using Chrome:
Conclusion
Well, that’s it for this series. I hope you enjoyed it, and make sure to check out the video below that walks you through everything I covered in this blog series (it’s true what they say: a video is worth a thousand pictures!).
Working with Kubernetes on your Computer (Minikube)
Hey everybody! In this post, I’d like to talk about Container-centric infrastructure with Kubernetes. This is Part 4 of a series of posts on using installing and using Kubernetes.
So now you’re finally ready to start using Kubernetes. The first step in deploying a containerized application is, well, the application. I’ve put together some demo JavaScript code that you’ll run as a Node.js application.
Open a Terminal window or command prompt, navigate to a location on your computer where you want the code to land and clone the code from GitHub.
Navigate to the kubernetes directory and take a look at the JavaScript code. This toy application doesn’t do anything serious, just outputs a message to the console. But it’s enough for our purposes here.
Now run the application in Node.
node k8sdemo.js
Open a browser and point it to http://localhost:8080 to see the message.
And there it is. Now that you have an application, it’s time to containerize it.
Containerize the application
Here’s how you use Docker to do that. Take a look at the Dockerfile:
FROM node:6.11.4
EXPOSE 8080
COPY k8sdemo.js .
CMD node k8sdemo.js
Use this Docker definition to containerize the application. But before we can do that we need to start minikube, and I’ll show you why in a minute.
Execute the minikube start command:
minikube start
The first time Minikube runs, it has to download the ISO image to run inside of VirtualBox, and may take a minute or two depending on the speed of your internet connection. Once the image has been downloaded, minikube will start.
Minikube runs inside VirtualBox in its own VM. We need to make sure that Docker uses the internal Docker registry on Minikube’s VM by executing this command:
eval $(minikube docker-env)
Otherwise Docker will use the local registry on your machine, which is not accessible from the VM where minikube is running.
Now, from the Terminal window, execute the docker build command:
docker build -t k8sdemo:v1 .
This will create the image with a name of k8sdemo and a tag of v1, and store it in the Docker registry on the minikube host VM. When deploying the image to Minikube, you’ll reference that tag explicitly.
From the Terminal window execute the kubectl run command:
kubectl run k8sdemo --image=k8sdemo:v1 --port=8080
And now the application is up and running in its own Pod.
Conclusion
In this post I showed you how to work with Kubernetes on your computer. You containerized a simple application, then deployed it to your local Kubernetes cluster.
In Part 5, I’ll show you how to manage an application running in a Kubernetes cluster using kubectl and the Kubernetes Web UI Dashboard.
Hey everybody! In this post, I’d like to talk about Container-centric infrastructure with Kubernetes. This is Part 3 of a series of posts on using installing and using Kubernetes.
If you missed Part 2 where I give you Kubernetes Overview, make sure to check that out.
In this post, I want to walk you through installing the software you need to run Kubernetes on your computer.
Install the software
You’ll need a few pieces of software to run Kubernetes on your computer:
Docker
VirtualBox (or some other virtualization software)
Node.js
Minikube
Install Docker
First, you need Docker. You can find instructions for your platform by clicking this link. If you already have Docker installed, skip to the next section.
Scroll down until you see your platform, which is MacOS in my case, so I’ll click on Docker for MacOS. I want the distribution from the Stable channel, so I click on the link that says Get Docker for Mac (Stable). Always verify the 256 bit SHA checksum of the downloaded file matches what is published.
Now double-click the DMG file to begin the installation, and follow the instructions.
Install VirtualBox
Minikube requires a virtualization environment in order to run. If you want to use software other than VirtualBox, check out the Getting Started with Minikube page at kubernetes.io. If you already have VirtualBox installed, skip to the next section.
To install VirtualBox, go to the VirtualBox installation page, and click on the link that matches your platform. ALWAYS verify the SHA256 checksum matches the downloaded file.
Now double-click the DMG file to begin the installation, and follow the instructions.
Install Node.js
In order to test the demo application, you’ll need Node.js installed. I already have Node.js installed on my Mac, so I’ll skip that for the video. Make sure to check out the Node.js installation page. If you already have Node.js installed, skip to the next section.
Click on the download link that matches your platform, and follow the instructions.
Install Minikube
Go to the Minikube page at GitHub, and look for Installation.
I like to use Homebrew to install software on my Mac. If you’re using Linux or Windows, the Minikube installation page has instructions for those platforms as well.
Drop out to a Terminal window and execute the brew cask install for Minikube:
brew cask install minikube
Homebrew installs Minikube and now it’s ready to go. Yes, it really is that easy (on MacOS anyway).
Conclusion
Now you have all the software you need to work with Kubernetes on your computer. Stay tuned for Part 4, where I’ll show you how to work with Minikube and define an application, deploy it to your local k8s cluster.
Hey everybody! In this post, I’d like to talk about Container-centric infrastructure with Kubernetes. This is Part 2 of a series of posts on using installing and using Kubernetes.
If you missed Part 1 where I talk about “Why Containers?”, make sure to check that out.
In this post, I want to give you an overiew of Kubernetes.
A Pod is where an application is deployed, and contains resources specific to an application, such as file storage.
Pods can contain multiple applications, and all applications in a Pod share the same IP address and port space. Think of a Pod as the logical host, and is the atomic unit of deployment and scheduling in a Kubernetes cluster.
A Node is a physical or virtual machine in the cluster, and runs one or more Pods.
Each running Pod with the same definition is called a replica, and a Pod can be instantiated more than once to improve application scalability within the cluster.
Desired state of the cluster
The job of Kubernetes – specifically the master – is the maintain the desired state of the cluster at all times. But what is the desired state?
The desired state is defined as the applications and workloads you want to run, what container images to use, the number of Pod replicas, and other stuff like network and disk resources that your applications need. The master compares the current state of the cluster to the desired state and if they differ, makes any necessary adjustments until the desired state is once again reached.
This is helpful for, say, when an application crashes. The master will detect the application is no longer running, and restart the it. Now the cluster is back to the desired state.
Conclusion
In this post I introduced you to Kubernetes.
Stay tuned for Part 3, where I walk you through installing all of the software you need to run Kubernetes on your computer!
If you use Docker and don’t use Kitematic, you’re missing out!
TL;DR
Kitematic is an awesome addition to your Docker toolbox. Download it here.
What is Kitematic?
It’s a graphical tool that lets you see what is running in your local Docker environment.
You’re probably used to docker ps, and docker images, and so on, to see what Docker is doing. But Kitematic can show you that information in a GUI.
So?
Okay, so I’m working on Part 3 of a tutorial series I’m doing for IBM developerWorks, and I have Hyperledger Fabric running in Docker.
Contrast this:
Ix:~ sperry$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c8e71d740f38 dev-peer0.org1.example.com-digitalproperty-network-0.14.3-b524d4b38bf773adade74e18741aacd93212883d30ef9b63def86797a270f038 "chaincode -peer.a..." 44 minutes ago Up 44 minutes dev-peer0.org1.example.com-digitalproperty-network-0.14.3
2931d5073686 dev-peer0.org1.example.com-perishable-network-0.14.3-02848cbd757516cb261270e628f79e44a5d478431848d48302bac059fa1b3fd5 "chaincode -peer.a..." 21 hours ago Up 21 hours dev-peer0.org1.example.com-perishable-network-0.14.3
9e4edf0acb21 hyperledger/fabric-peer:x86_64-1.0.3 "peer node start -..." 21 hours ago Up 21 hours 0.0.0.0:7051->7051/tcp, 0.0.0.0:7053->7053/tcp peer0.org1.example.com
7392660e2da1 hyperledger/fabric-ca:x86_64-1.0.3 "sh -c 'fabric-ca-..." 21 hours ago Up 21 hours 0.0.0.0:7054->7054/tcp ca.org1.example.com
61ffea441cc6 hyperledger/fabric-orderer:x86_64-1.0.3 "orderer" 21 hours ago Up 21 hours 0.0.0.0:7050->7050/tcp orderer.example.com
8034e8baa63e hyperledger/fabric-couchdb:x86_64-1.0.3 "tini -- /docker-e..." 21 hours ago Up 21 hours 4369/tcp, 9100/tcp, 0.0.0.0:5984->5984/tcp couchdb
Ix:~ sperry$
With this:
You can see the same info, but in a GUI format. Now, I love the command line as much as anybody, but sometimes figuring out what is going on with Docker through the command line can be frustrating. Not that the information isn’t there; just that it’s not super easy to tease out the information I’m looking for.
What else?
With Kitematic, you can see the logs for each container, just as you can with the docker logs command.
Compare this:
$ docker logs 61ffea441cc6
2017-11-05 20:19:38.265 UTC [orderer/main] main -> INFO 001 Starting orderer:
Version: 1.0.3
Go version: go1.7.5
OS/Arch: linux/amd64
2017-11-05 20:19:38.274 UTC [bccsp_sw] openKeyStore -> DEBU 002 KeyStore opened at [/etc/hyperledger/msp/orderer/msp/keystore]...done
2017-11-05 20:19:38.274 UTC [bccsp] initBCCSP -> DEBU 003 Initialize BCCSP [SW]
2017-11-05 20:19:38.275 UTC [msp] getPemMaterialFromDir -> DEBU 004 Reading directory /etc/hyperledger/msp/orderer/msp/signcerts
.
.
2017-11-06 16:49:34.979 UTC [fsblkstorage] updateCheckpoint -> DEBU a7f Broadcasting about update checkpointInfo: latestFileChunkSuffixNum=[0], latestFileChunksize=[213666], isChainEmpty=[false], lastBlockNumber=[7]
2017-11-06 16:49:34.979 UTC [orderer/multichain] WriteBlock -> DEBU a80 [channel: composerchannel] Wrote block 7
2017-11-06 16:49:34.979 UTC [fsblkstorage] retrieveBlockByNumber -> DEBU a81 retrieveBlockByNumber() - blockNum = [7]
2017-11-06 16:49:34.979 UTC [fsblkstorage] newBlockfileStream -> DEBU a82 newBlockfileStream(): filePath=[/var/hyperledger/production/orderer/chains/composerchannel/blockfile_000000], startOffset=[205101]
2017-11-06 16:49:34.979 UTC [fsblkstorage] nextBlockBytesAndPlacementInfo -> DEBU a83 Remaining bytes=[8565], Going to peek [8] bytes
2017-11-06 16:49:34.979 UTC [fsblkstorage] nextBlockBytesAndPlacementInfo -> DEBU a84 Returning blockbytes - length=[8563], placementInfo={fileNum=[0], startOffset=[205101], bytesOffset=[205103]}
2017-11-06 16:49:34.979 UTC [orderer/common/deliver] Handle -> DEBU a85 [channel: composerchannel] Delivering block for (0xc4208547c0)
With this:
You can see the logs (under the Home tab on the right-hand side of the UI), in addition to information about the port that is exposed on localhost, the volumes that are mounted, and settings for both.
Get Kitematic
How do you use Kitematic? Go to the Docker drop-down menu in the status tray (mine is at the top of the screen on my Mac),
And select Kitematic. The first time you do this, you’ll see this dialog:
Click the “here” link (which takes you to https://download.docker.com/kitematic/Kitematic-Mac.zip). Once the ZIP file is downloaded, unzip it. It contains the Kitematic app, which you then drag and drop into your Applications folder. The next time you select Kitematic from the Docker drop-down, it fires up seamlessly.
You can sign into Docker Hub if you have an ID (if not, just select “Skip for Now”).
That’s it! Now you can use Kitematic.
Fini
I’m not suggesting you shouldn’t use the Docker command line tools. They’re great. But Kitematic is another tool in your Docker arsenal.
Hey everybody! In this post, I’d like to talk about Container-centric infrastructure with Kubernetes. This is Part 1 of a series of posts on using installing and using Kubernetes.
Before containers, we installed applications directly on the target host, along with libraries our apps needed, plus the libraries any other applications needed as well.
At best, it presents DevOps with maintenance challenges. And at worst, integration conflicts between applications, versions of dependent libraries, and so on, can lead to poor application performance and even downtime.
Container-Centric infrastructure
With containers, on the other hand, all the applications run in their own isolated mini environments, away from each other, and the underlying OS.
And this is what you get with Kubernetes!
Conclusion
Container-centric infrastructure like that provided by Kubernetes has tremendous benefits, and in Part 2 I’ll give you an overview of Kubernetes, and talk about Pods, Nodes, and the “desired state” of the cluster. Stay tuned for that.
In order to run JUnit tests, you need to tell the JUnit Platform about your test classes: which methods are test methods, which methods are part of the test method lifecycle, whether to use extensions, and so on.
You do this through annotations, which are metadata about how to run your tests.
You can download the code from GitHub if you like:
In this post, I’ll cover the two annotations you’re likely to use with JUnit, along with examples of each.
@Test
@Test
@DisplayName("When numbers are > 0")
public void testAdd() {
// Unit test code here
}
Use this annotation to tell the JUnit platform that the method is a test method. This means it will be invoked at the appropriate point in the lifecycle, complete with all the bells and whistles.
Every method you want to run as a test method needs to be annotated with the @Test annotation.
@DisplayName
@DisplayName("Testing using JUnit 5")
public class JUnit5AppTest {
.
.
@Test
@DisplayName("When numbers are > 0")
public void testAdd() {
// Unit test code here
}
.
.
}
By default, the name displayed for a test class or method is the name of the class or method, respectively. The @DisplayName annotation tells JUnit to use the specified name instead.
Check it out: compare the following examples, first without the annotation, then with it. (Both are from the JUnit View in Eclipse)
Without the @DisplayName annotation:
And with the @DisplayName annotation:
In this simple example, you can see already that the report is cleaner. But when there are several test methods, the value of @DisplayName gets even clearer:
Video
In the video below, I’ll go over the annotations in detail, and you can watch me explain the code as I write it.
Conclusion
In this article, I showed you two of the annotations from the JUnit Jupiter API you’ll definitely want to use. Stay tuned for more in this series, where I’ll show you more annotations from the JUnit Jupiter API.
Be sure to follow along with this series here on my blog, and the accompanying videos on my YouTube channel.
To learn more about the annotations provided by the JUnit Jupiter API visit the JUnit 5 User’s Guide.
Check out my IBM developerWorks JUnit 5 Tutorial Series:
You must be logged in to post a comment.