Skip to content

Commit f37a7b1

Browse files
committed
Some more fixes and progress getting tests further in 9
1 parent d9b7a8f commit f37a7b1

File tree

5 files changed

+48
-39
lines changed

5 files changed

+48
-39
lines changed

chapter_09_docker.asciidoc

Lines changed: 31 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -579,10 +579,13 @@ An image is essentially a pre-prepared root filesystem,
579579
including the operating system, dependencies, and any code you want to run.
580580

581581
Once you have an image, you can run one or many containers that use the same image.
582+
It's a bit like saying, once you've installed your operating system and software,
583+
you can start up your computer and run that software any number of times,
584+
without needing to change anything else.
585+
586+
Another way of thinking about it is, images are like classes,
587+
and containers are like instances.
582588

583-
// DAVID: Not sure whether this is going to be understandable in its current form.
584-
// An analogy that I find helpful here is that images are like classes
585-
// and containers are like instances.
586589

587590
==== A First Cut of a Dockerfile
588591

@@ -599,13 +602,7 @@ What do we need to do? Something like this, right?
599602
We create a new file called _Dockerfile_ in the base folder of our repo,
600603
next to the `src/` directory we made earlier:
601604

602-
// DAVID: As discussed, I misread this and put the Dockerfile in src.
603-
// That led to a difficult to understand error message when I tried to build.
604-
// ERROR: failed to solve: failed to compute cache key: failed to calculate
605-
// checksum of ref e126cbb4-3e0c-4e6e-867f-dbfbf5fb190f::k2oys44pcnbefrlpps3ooux7w: "/src": not found
606-
607605
// JAN: I'd suggest to use python3.11:slim or python3:12 slim. Keeping image tags too open leads to issues in a couple of months (not always, but waaay too often)
608-
// JAN: I'd use Docker comments with # for <1>, <2>, ... Otherwise, you need to edit the code when you paste it
609606

610607

611608

@@ -708,12 +705,14 @@ $ pass:quotes[*docker build -t superlists .*]
708705

709706
Now we can see our image in the list of docker images on the system:
710707

708+
// TODO, this listing was hard to test due to column widths but there must be a way
709+
[role="skipme"]
711710
[subs="specialcharacters,quotes"]
712711
----
713712
$ *docker images*
714713
REPOSITORY TAG IMAGE ID CREATED SIZE
715-
[...]
716714
superlists latest 522824a399de 2 minutes ago 164MB
715+
[...]
717716
----
718717

719718

@@ -754,18 +753,18 @@ environment?
754753
----
755754

756755

757-
// DAVID: I got:
758-
// python: can't open file '/src/manage.py': [Errno 2] No such file or directory
759-
760756
Ah, we forgot that we need to install Django.
761757

762758

763-
=== Installing Django into our Virtualenv
759+
=== Installing Django in a Virtualenv in our Container Image
764760

765761
Just like on our own machine,
766762
a virtualenv is useful in a deployed environment to make
767-
sure we have full control over the packages installed for a particular
768-
project.
763+
sure we have full control over the packages installed
764+
for a particular project.footnote:[
765+
Even a completely fresh Linux install might have odd things installed
766+
in its system site packages.
767+
A virtualenv is a guaranteed clean slate.]
769768

770769
We can create a virtualenv in our Dockerfile
771770
just like we did on our own machine with `python -m venv`,
@@ -802,7 +801,6 @@ CMD python manage.py runserver
802801
<3> We install Django with `pip install`, just like we do locally.
803802

804803

805-
// DAVID: Why bother with a virtualenv?
806804

807805
==== Successful Run
808806

@@ -983,9 +981,9 @@ Try it on your own computer first:
983981
----
984982
$ pass:quotes[*curl -iv localhost:8888*]
985983
* Trying 127.0.0.1:8888...
986-
* connect to 127.0.0.1 port 8888 failed: Connection refused
984+
* connect to 127.0.0.1 port 8888 [...]
987985
* Trying [::1]:8888...
988-
* connect to ::1 port 8888 failed: Connection refused
986+
* connect to ::1 port 8888 [...]
989987
* Failed to connect to localhost port 8888 after 0 ms: Couldn't connect to
990988
server
991989
* Closing connection
@@ -1046,10 +1044,10 @@ The following additional packages will be installed:
10461044
[...]
10471045
root@5ed84681fdf8:/src# pass:quotes[*curl -iv http://localhost:8888*]
10481046
* Trying 127.0.0.1:8888...
1049-
* Connected to localhost (127.0.0.1) port 8888 (#0)
1047+
* Connected to localhost (127.0.0.1) port 8888
10501048
> GET / HTTP/1.1
10511049
> Host: localhost:8888
1052-
> User-Agent: curl/7.88.1
1050+
> User-Agent: curl/8[...]
10531051
> Accept: */*
10541052
>
10551053
< HTTP/1.1 200 OK
@@ -1120,27 +1118,30 @@ Similarly, if you try our `curl -iv` (outside the container) once again,
11201118
you'll see the error has changed from "Failed to connect",
11211119
to "Empty reply":
11221120

1123-
[role="ignore-errors"]
1121+
[role="ignore-errors pause-first"]
11241122
[subs="specialcharacters,macros"]
11251123
----
11261124
$ pass:quotes[*curl -iv localhost:8888*]
11271125
* Trying 127.0.0.1:8888...
11281126
* Connected to localhost (127.0.0.1) port 8888
11291127
> GET / HTTP/1.1
11301128
> Host: localhost:8888
1131-
> User-Agent: curl/7.88.1
1129+
> User-Agent: curl/8.[...]
11321130
> Accept: */*
11331131
[...]
11341132
* Empty reply from server
1135-
* Closing connection 0
1133+
* Closing connection
11361134
curl: (52) Empty reply from server
11371135
----
11381136

1137+
////
1138+
11391139
NOTE: Depending on your system, instead of `(52) Empty reply from server`,
11401140
You might see `(56) Recv failure: Connection reset by peer`.
11411141
They mean the same thing.
11421142
1143-
//TODO: double-check what the difference means here.
1143+
TODO: double-check what the difference means here.
1144+
////
11441145

11451146

11461147
==== Essential Googling the Error Message
@@ -1188,6 +1189,9 @@ using the magic "wilcard" IP address `0.0.0.0`:
11881189
// DAVID: Some readers might not be that comfortable with the idea of ports.
11891190
// I think this could do with more explanation.
11901191

1192+
1193+
1194+
[role="sourcecode"]
11911195
.Dockerfile (ch09l007)
11921196
====
11931197
[source,dockerfile]
@@ -1212,17 +1216,17 @@ Starting development server at http://0.0.0.0:8888/
12121216

12131217
We can verify it's working with `curl`:
12141218

1219+
[role="pause-first"]
12151220
[subs="specialcharacters,macros"]
12161221
----
12171222
$ pass:quotes[*curl -iv localhost:8888*]
12181223
* Trying 127.0.0.1:8888...
1219-
* Connected to localhost (127.0.0.1) port 8888 (#0)
1224+
* Connected to localhost (127.0.0.1) port 8888
12201225
[...]
12211226
12221227
</body>
12231228
12241229
</html>
1225-
* Connection #0 to host localhost left intact
12261230
----
12271231

12281232
Looking good!

tests/book_parser.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ def __init__(self, filename, contents):
2424
self.skip = False
2525
self.currentcontents = False
2626
self.against_server = False
27+
self.pause_first = False
2728

2829
def is_diff(self):
2930
lines = self.contents.split("\n")
@@ -56,6 +57,7 @@ def __init__(self, a_string):
5657
self.ignore_errors = False
5758
self.server_command = False
5859
self.against_server = False
60+
self.pause_first = False
5961
self.dofirst = None
6062
str.__init__(a_string)
6163

@@ -93,6 +95,7 @@ def __init__(self, a_string):
9395
self.dofirst = None
9496
self.jasmine_output = False
9597
self.against_server = False
98+
self.pause_first = False
9699
str.__init__(a_string)
97100

98101
@property
@@ -216,6 +219,10 @@ def parse_listing(listing): # noqa: PLR0912
216219
for listing in outputs:
217220
listing.against_server = True
218221

222+
if "pause-first" in classes:
223+
for listing in outputs:
224+
listing.pause_first = True
225+
219226
return outputs
220227

221228

tests/book_tester.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -732,6 +732,9 @@ def run_interactive_manage_py(self, listing):
732732

733733
def recognise_listing_and_process_it(self):
734734
listing = self.listings[self.pos]
735+
if listing.pause_first:
736+
print('pausing first')
737+
time.sleep(2)
735738
if listing.dofirst:
736739
print("DOFIRST", listing.dofirst)
737740
self.sourcetree.patch_from_commit(
@@ -805,7 +808,7 @@ def recognise_listing_and_process_it(self):
805808

806809
elif listing.type == "docker run tty":
807810
self.sourcetree.run_command(
808-
"docker kill $(docker ps -q)", ignore_errors=True
811+
"docker kill $(docker ps -q)", ignore_errors=True, silent=True
809812
)
810813
fixed = Command(listing.replace(" -it ", " -t "))
811814
next_listing = self.listings[self.pos + 1]

tests/test_book_tester.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -600,7 +600,8 @@ def test_only_ignores_exactly_32_char_strings_no_whitespace(self):
600600

601601
def test_ignores_docker_image_ids_and_creation_time(self):
602602
actual = "superlists latest 522824a399de 2 weeks ago 164MB"
603-
expected = Output("superlists latest 522824a399de 2 minutes ago 164MB")
603+
expected = Output("superlists latest 622824a399de 2 minutes ago 164MB")
604+
actual = "superlists latest 4856d33cf356 55 minutes ago 167MB"
604605
self.assert_console_output_correct(actual, expected)
605606
self.assertTrue(expected.was_checked)
606607
with self.assertRaises(AssertionError):

tests/test_chapter_09_docker.py

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
#!/usr/bin/env python3
2-
import unittest
2+
import os
33
import subprocess
4+
import unittest
45

5-
from book_tester import ChapterTest, DO_SERVER_COMMANDS
6+
from book_tester import DO_SERVER_COMMANDS, ChapterTest
67

78

89
class Chapter9Test(ChapterTest):
@@ -28,8 +29,7 @@ def test_listings_and_commands_and_output(self):
2829
vm_restore = None # 'MANUAL_1'
2930

3031
# hack fast-forward
31-
skip = True
32-
if skip:
32+
if os.environ.get("SKIP"):
3333
self.pos = 8
3434
# self.pos = 18
3535
self.sourcetree.run_command(
@@ -46,12 +46,6 @@ def test_listings_and_commands_and_output(self):
4646
subprocess.check_call(["vagrant", "up"])
4747

4848
while self.pos < len(self.listings):
49-
if self.pos == 47:
50-
assert "curl -iv" in self.listings[self.pos]
51-
print('sleeping')
52-
# breakpoint()
53-
import time; time.sleep(1)
54-
5549
listing = self.listings[self.pos]
5650
print(self.pos, listing.type, repr(listing))
5751
self.recognise_listing_and_process_it()

0 commit comments

Comments
 (0)