yaymukund’s weblog

How to spy on your Rust code

In the following code, how can you test that Player is making the correct API calls?

struct Player<'a> {
  api: &'a Api,
}

impl<'a> Player<'a> {
  pub fn new(api: &'a Api) -> Player<'a> {
    Player { api }
  }

  pub fn play(&self, song: &str) {
    self.api.sing(song);
  }

  pub fn stop(&self) {
    self.api.shush();
  }
}

The answer? Make it generic!

struct Player<'a, T> {
  api: &'a T,
}

impl<'a, T> Player<'a, T>
where
  T: PlayerApi,
{
  pub fn new(api: &'a T) -> Player<'a, T> {
    Player { api }
  }

  // ...
}

trait PlayerApi {
  // Default trait implementation uses `Api`
  fn sing(&self, url: &str);
  fn shush(&self);
}

impl PlayerApi for Api {
  fn sing(&self, url: &str) {
    Api::sing(self, url)
  }

  fn shush(&self) {
    Api::shush(self)
  }
}

Then you can easily spy on it:

#[cfg(test)]
module Test {
  struct ApiSpy {
    pub invocations: Vec<String>,
    api: Api,
  }

  impl ApiSpy {
    pub fn new() -> ApiSpy {
      ApiSpy { api: Api::New() }
    }
  }

  impl PlayerApi for ApiSpy {
    fn sing(&self, url: &str) {
      self.invocations.push('play');
      self.api.sing(url)
    }
  }

  #[test]
  fn test_play() {
    let api = ApiMock::new();
    let player = Player::new(&api);
    player.play("my_url");
    assert_eq!(api.invocations[0], "play");
  }
}

That’s it!

How can I assert that I passed the correct arguments?

You can store the arguments in the ApiSpy. For example, here’s how I mocked the mpv api and used it in a test.

I don’t want to define a trait for my API just for tests!

Defining a trait for your external APIs is good for reasons beyond testing. But if you still still don’t want to make your API generic, then you could use conditional compilation instead..

What if I don’t want to execute API code in tests?

If you want to mock instead of spy, you have a couple options:

Wireless printers on swaywm

Here’s how you add a wireless printer to Sway. You’ll need the following tools:

  1. CUPS, the “standards-based, open source printing system”
  2. Avahi for wireless support
  3. nss-mdns, so we can refer to the printer as <hostname>.local (e.g. myprinter.local)
# Install the packages
$ yay -S cups avahi nss-mdns

# Start the cups service
$ systemctl start org.cups.cupsd.service

# Ensure you can see the CUPS web interface at localhost:631

# Start the Avahi daemon
$ systemctl start avahi-daemon.service

Now, enable hostname resolution in Avahi by following the instructions on the Arch Wiki.

# Find the printer on the local network
$ sudo lpinfo --include-schemes dnssd -v

# You should see something like:
# network dnssd://Canon%20MG5700%20series._ipp._tcp.local/?uuid=<some uuid>

# Add the printer to CUPS
$ sudo lpadmin \
  -p short-name-eg-canon-md5750 \
  -D "Full Name (e.g. 'Canon MG5750 Laserjet')" \
  -L "Location (e.g. 'Living Room') (Optional)" \
  -v dnssd://Canon%20MG5700...

If you did everything right so far, you should be able to see the printer in the CUPS web interface (localhost:631). If you click on the printer’s name, it should say “Idle, Accepting Jobs.”

Now, you can try to print your document. You can track your print job from the CUPS web interface. If something goes wrong, you can see the error there.

Bonus! Add custom printer drivers

To access advanced features of your printer, you may need to install a custom driver. First, find the relevant drivers by searching the AUR for your printer model. For me, it was the cnijfilter2-mg7700 package.

Once you’ve done that, tell CUPS to assign the custom driver to the printer:

# Find the driver's ppd file
$ lpinfo -m
# It will be something like lsb/usr/canonmg5700.ppd

# And assign it in CUPS
$ sudo lpadmin -p canon-md5750 -m lsb/usr/canonmg5700.ppd

That’s it!

Troubleshooting

My printer in CUPS is listed as disabled or not accepting new jobs

Make sure you run:

$ sudo cupsenable $short_name
$ sudo cupsaccept $short_name

You may be able to do this from the web interface, but I was getting permission denied errors.

My print job fails because it can’t find ghostscript

You need to install ghostscript. In Arch, it’s just yay -S ghostscript.

References

By translating these poems, we aim to memorialize Xu, share some of his excellent literary work, and spread awareness that the harsh conditions, struggles and aspirations of Chinese migrant workers (including but not limited to Foxconn) have not diminished since the more widely-publicized spate of 18 attempted Foxconn suicides in 2010, resulting in 14 deaths. Insiders report that thereafter, although the frequency of suicides decreased (mainly due to Foxconn’s installation of nets making it more difficult for workers to jump from their dormitories, along with the development of workers’ collective resistance), such suicides have continued to the present. Including Xu Lizhi, at least 8 cases have been reported in the media since 2010, but insiders say that many other cases go unreported. We hope that in the future, workers in Foxconn and elsewhere manage to find ways around such companies’ military-style discipline and surveillance, come together, and forge collective paths out of this capitalist world of death, into a world worth living in. Don’t give up!

Source: libcom.org/blog/xulizhi-foxconn-suicide-poetry

On My Deathbed

I want to take another look at the ocean, behold the vastness of tears from half a lifetime
I want to climb another mountain, try to call back the soul that I’ve lost
I want to touch the sky, feel that blueness so light
But I can’t do any of this, so I’m leaving this world
Everyone who’s heard of me
Shouldn’t be surprised at my leaving
Even less should you sigh or grieve
I was fine when I came, and fine when I left.

– Xu Lizhi, 30 September 2014

Looking to keep the [Soviet–Afghan] war fueled, Washington– where the prevailing ethos was to bleed the Russians until the last Afghan– financed textbooks for schoolchildren in refugee camps that were festooned with illustrations of Kalashnikovs, swords, and overturned tanks. One such edition declared: “Jihad is a kind of war that Muslims fight in the name of God to free Muslims… If infidels invade, jihad is the obligation of every Muslim.” An American text designed to teach children the Farsi alphabet began

Aleph [is for] Allah; Allah is one

Bey [is for] Baba (father); Father goes to the mosque

Tey [is for] Tofang (rifle); Javed obtains rifles for the mujahedeen

Jeem [is for] Jihad; Jihad is an obligation. My mom went to the jihad.

No Good Men Among The Living (2014) by Anand Gopal

One result of all the outside attention was the 2004 constitution [of Afghanistan], drafted with heavy Western input and hailed as one of the world’s most progressive. In addition to protecting basic civil liberties and minority rights, the document guaranteed women 25 percent of parliamentary seats (surpassing the proportion in the US Congress).

No Good Men Among The Living (2014) by Anand Gopal

Something that Republican presidents love to do on their first day of office which is reinstate something known as the “global gag rule,” which is that agencies around the world which receive US support for their health programs are not allowed to provide abortion of contraception services or even talk about them– hence the name “gag rule.”

We love when we talk about foreign and national security policy to focus on the high geopolitics– “what does it mean the Kurds versus versus the Shia versus the Turks?”– but that global gag rule is gonna affect the lives of as many women and families as anything else Donald Trump does his first hundred days in office. Their lives are always on the line when Americans vote and it’s not something we ever talk about or think about but it’s a very real consequence of what happened last night.

– Heather Hurlburt on Global Dispatches, “The Foreign Policy of Donald Trump” (25:07)

This past January, when I started [teaching the post-emancipation African American history survey course], Obama was running in the primary against Hillary Clinton. Many of us still presumed that Clinton was going to be the nominee and then Obama became a movement over the next several months.

I was watching this transpire in my course. I told my students in the beginning of the course I would not be talking about the election until the end of the course because this is a class of history. But I guaranteed them that there would be themes every week in the election in the primary battles that linked what happened in January 31, 2008 to discussions of what’s happening in Reconstruction America. These narratives that Glenda [Gilmore] has already alluded to– white womanhood, the threat of the black male– these are long, long narratives and I simply can’t believe that those narratives are going to disappear.

Maybe. Maybe– I doubt it– but maybe they’ve altered somehow. Let’s just see what happens once maybe the economy gets better or maybe once middle east strife becomes less confusing. I think that role of the racial specter can come up much more easily when we’re not all hurting so much.

– Jonathan Holloway in Three Yale Historians Discuss the Election of Barack Obama (soundcloud, 2008)

Working-class politics had so little room to maneuver in hard times that racial sympathy was shoved aside. In a famous 1844 public correspondence with the abolitionist Gerrit Smith, labor reformer George Henry Evans spoke for many labor leaders when he declared himself “formerly” an advocate of abolition: “This was before I saw that there was white slavery.”

[…]

Workers on the very bottom may have negotiated the cementing of their class position beneath the artisan class by denying that position through celebrations of their free-white status as well as embracing it through unseemly– and unrepublican– activities such as racist mobbing and other forms of public racial antagonism. Thus did popular racism aid the formation of the white working class: “whiteness” was capacious enough to allow entry to almost any nonblack worker, and resilient enough to mask the class tensions that were worked out in the modality of race.

Love & Theft: Blackface Minstrelsy and the American Working Class (1993) by Eric Lott

It may surprise you or not surprise you that when we went to Iraq in 2007, General Petraeus and I said, “Do you know why these people fighting? Show us the data,” no study like the Vietcong Motivation & Morale Study (1966), pdf had ever been done. That was the period when the Secretary of Defense and military commander on the ground used to describe the enemy as “evil-doers” and say that “the evil-doers hate us because they hate who we are, not because of what we do.” And we said, well, let’s look into that.

[…]

Based on [a survey of 24,000 people in detention]– which was partly quantitative and partly based on interviews– we determined that 70% of the people were fighting us primarily for economic reasons. Another 20% were fighting us because they had belonged to a former regime group for a formerly dominant social group that had been dispossessed by what happened in Iraq after 2003. They were fighting us to reestablish their position of social or political ascendancy. Less than 10% of the people that we were fighting were motivated predominately by religious motivation or ideology associated with Al-Qaeda. And in fact, a high proportion those 10% were foreigners; they weren’t even from Iraq. So that’s the sort of data set for Iraq and we did similar surveys in Afghanistan later the tended to show that basically what you have on on the ground in most cases is a very, very small number of irreconcilable fanatics who draw their power from their ability to intimidate, manipulate, and mobilize a much larger group of people who are fighting us primarily because we’re in their space and feel like they need to defend themselves rather than because they naturally support that small extremist clique.

– David Kilcullen on Accidental Guerrilla Warfare in the Midst of War (youtube)

The destroyers of the tea were dressed to look like indians and also professed imitate their speech they gave a “War Whoop” and the chiefs among them used an otherwise “unintelligible” mock Indian language which was then supposedly relayed to the other men aboard the ships via an interpreter. Accounts at that time noted the dialect, the “jargon” were the “most hideous Noise” that the participants in the Boston Tea Party had made. (These are all quotes from contemporary accounts.)

[…]

The blacksmith Joshua Wyeth was a participant in the Tea Party. He later remembered “We surely resembled Devils from the bottomless pit rather than men.” The loyalist Peter Oliver we’ve agreed in his account he later wrote, “it was the Rule of Faction”– in other words it was the way of the Sons of Liberty– “to make their Agents first look like the Devil in Order to make them Act like the Devil.”

– Professor Benjamin L. Carp on Resolute Men (Dressed As Mohawks) (youtube)